|
1 | 1 | use std::env; |
2 | 2 | use std::path::PathBuf; |
3 | 3 |
|
4 | | -use crate::core::build_steps::tool::Tool; |
5 | | -use crate::core::builder::{self, Builder, Kind}; |
| 4 | +use crate::core::build_steps::compile; |
| 5 | +use crate::core::build_steps::tool::{self, Tool}; |
| 6 | +use crate::core::builder::{self, Builder, Compiler, Kind, ShouldRun, Step}; |
6 | 7 | use crate::core::config::TargetSelection; |
7 | | -use crate::utils::exec::BootstrapCommand; |
8 | | -use crate::utils::helpers::{self, dylib_path, dylib_path_var}; |
| 8 | +use crate::utils::exec::{BootstrapCommand, command}; |
| 9 | +use crate::utils::helpers::{self, dylib_path, dylib_path_var, t}; |
9 | 10 | use crate::utils::render_tests::add_flags_and_try_run_tests; |
10 | 11 | use crate::{DocTests, envify}; |
11 | 12 |
|
@@ -122,3 +123,55 @@ pub(super) fn prepare_cargo_test( |
122 | 123 |
|
123 | 124 | cargo |
124 | 125 | } |
| 126 | + |
| 127 | +/// Some test suites are run inside emulators or on remote devices, and most of our test binaries |
| 128 | +/// are linked dynamically which means we need to ship the standard library and such to the emulator |
| 129 | +/// ahead of time. This step represents this and is a dependency of all test suites. |
| 130 | +/// |
| 131 | +/// Most of the time this is a no-op. For some steps such as shipping data to QEMU we have to build |
| 132 | +/// our own tools so we've got conditional dependencies on those programs as well. Note that the |
| 133 | +/// remote test client is built for the build target (us) and the server is built for the target. |
| 134 | +#[derive(Debug, Clone, PartialEq, Eq, Hash)] |
| 135 | +pub(super) struct RemoteCopyLibs { |
| 136 | + pub(super) compiler: Compiler, |
| 137 | + pub(super) target: TargetSelection, |
| 138 | +} |
| 139 | + |
| 140 | +impl Step for RemoteCopyLibs { |
| 141 | + type Output = (); |
| 142 | + |
| 143 | + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { |
| 144 | + run.never() |
| 145 | + } |
| 146 | + |
| 147 | + fn run(self, builder: &Builder<'_>) { |
| 148 | + let compiler = self.compiler; |
| 149 | + let target = self.target; |
| 150 | + if !builder.remote_tested(target) { |
| 151 | + return; |
| 152 | + } |
| 153 | + |
| 154 | + builder.ensure(compile::Std::new(compiler, target)); |
| 155 | + |
| 156 | + builder.info(&format!("REMOTE copy libs to emulator ({target})")); |
| 157 | + |
| 158 | + let server = builder.ensure(tool::RemoteTestServer { compiler, target }); |
| 159 | + |
| 160 | + // Spawn the emulator and wait for it to come online |
| 161 | + let tool = builder.tool_exe(Tool::RemoteTestClient); |
| 162 | + let mut cmd = command(&tool); |
| 163 | + cmd.arg("spawn-emulator").arg(target.triple).arg(&server).arg(builder.tempdir()); |
| 164 | + if let Some(rootfs) = builder.qemu_rootfs(target) { |
| 165 | + cmd.arg(rootfs); |
| 166 | + } |
| 167 | + cmd.run(builder); |
| 168 | + |
| 169 | + // Push all our dylibs to the emulator |
| 170 | + for f in t!(builder.sysroot_target_libdir(compiler, target).read_dir()) { |
| 171 | + let f = t!(f); |
| 172 | + if helpers::is_dylib(&f.path()) { |
| 173 | + command(&tool).arg("push").arg(f.path()).run(builder); |
| 174 | + } |
| 175 | + } |
| 176 | + } |
| 177 | +} |
0 commit comments