|
9 | 9 | //!
|
10 | 10 | //! These tests are all disabled on rust-lang/rust's CI, but run in Cargo's CI.
|
11 | 11 |
|
12 |
| -use crate::{basic_manifest, main_file, project}; |
13 |
| -use cargo_util::ProcessError; |
14 | 12 | use std::env;
|
15 |
| -use std::fmt::Write; |
16 |
| -use std::process::{Command, Output}; |
17 |
| -use std::sync::atomic::{AtomicBool, Ordering}; |
18 |
| -use std::sync::Once; |
19 |
| - |
20 |
| -/// Whether or not the resulting cross binaries can run on the host. |
21 |
| -static CAN_RUN_ON_HOST: AtomicBool = AtomicBool::new(false); |
22 |
| - |
23 |
| -pub fn disabled() -> bool { |
24 |
| - // First, disable if requested. |
25 |
| - match env::var("CFG_DISABLE_CROSS_TESTS") { |
26 |
| - Ok(ref s) if *s == "1" => return true, |
27 |
| - _ => {} |
28 |
| - } |
29 |
| - |
30 |
| - // It requires setting `target.linker` for cross-compilation to work on aarch64, |
31 |
| - // so not going to bother now. |
32 |
| - if cfg!(all(target_arch = "aarch64", target_os = "linux")) { |
33 |
| - return true; |
34 |
| - } |
35 |
| - |
36 |
| - // Cross tests are only tested to work on macos, linux, and MSVC windows. |
37 |
| - if !(cfg!(target_os = "macos") || cfg!(target_os = "linux") || cfg!(target_env = "msvc")) { |
38 |
| - return true; |
39 |
| - } |
40 |
| - |
41 |
| - // It's not particularly common to have a cross-compilation setup, so |
42 |
| - // try to detect that before we fail a bunch of tests through no fault |
43 |
| - // of the user. |
44 |
| - static CAN_BUILD_CROSS_TESTS: AtomicBool = AtomicBool::new(false); |
45 |
| - static CHECK: Once = Once::new(); |
46 |
| - |
47 |
| - let cross_target = alternate(); |
48 |
| - |
49 |
| - let run_cross_test = || -> anyhow::Result<Output> { |
50 |
| - let p = project() |
51 |
| - .at("cross_test") |
52 |
| - .file("Cargo.toml", &basic_manifest("cross_test", "1.0.0")) |
53 |
| - .file("src/main.rs", &main_file(r#""testing!""#, &[])) |
54 |
| - .build(); |
55 |
| - |
56 |
| - let build_result = p |
57 |
| - .cargo("build --target") |
58 |
| - .arg(&cross_target) |
59 |
| - .exec_with_output(); |
60 |
| - |
61 |
| - if build_result.is_ok() { |
62 |
| - CAN_BUILD_CROSS_TESTS.store(true, Ordering::SeqCst); |
63 |
| - } |
64 |
| - |
65 |
| - let result = p |
66 |
| - .cargo("run --target") |
67 |
| - .arg(&cross_target) |
68 |
| - .exec_with_output(); |
69 |
| - |
70 |
| - if result.is_ok() { |
71 |
| - CAN_RUN_ON_HOST.store(true, Ordering::SeqCst); |
72 |
| - } |
73 |
| - build_result |
74 |
| - }; |
75 |
| - |
76 |
| - CHECK.call_once(|| { |
77 |
| - drop(run_cross_test()); |
78 |
| - }); |
79 |
| - |
80 |
| - if CAN_BUILD_CROSS_TESTS.load(Ordering::SeqCst) { |
81 |
| - // We were able to compile a simple project, so the user has the |
82 |
| - // necessary `std::` bits installed. Therefore, tests should not |
83 |
| - // be disabled. |
84 |
| - return false; |
85 |
| - } |
86 |
| - |
87 |
| - // We can't compile a simple cross project. We want to warn the user |
88 |
| - // by failing a single test and having the remainder of the cross tests |
89 |
| - // pass. We don't use `std::sync::Once` here because panicking inside its |
90 |
| - // `call_once` method would poison the `Once` instance, which is not what |
91 |
| - // we want. |
92 |
| - static HAVE_WARNED: AtomicBool = AtomicBool::new(false); |
93 |
| - |
94 |
| - if HAVE_WARNED.swap(true, Ordering::SeqCst) { |
95 |
| - // We are some other test and somebody else is handling the warning. |
96 |
| - // Just disable the current test. |
97 |
| - return true; |
98 |
| - } |
99 |
| - |
100 |
| - // We are responsible for warning the user, which we do by panicking. |
101 |
| - let mut message = format!( |
102 |
| - " |
103 |
| -Cannot cross compile to {}. |
104 |
| -
|
105 |
| -This failure can be safely ignored. If you would prefer to not see this |
106 |
| -failure, you can set the environment variable CFG_DISABLE_CROSS_TESTS to \"1\". |
107 |
| -
|
108 |
| -Alternatively, you can install the necessary libraries to enable cross |
109 |
| -compilation tests. Cross compilation tests depend on your host platform. |
110 |
| -", |
111 |
| - cross_target |
112 |
| - ); |
113 |
| - |
114 |
| - if cfg!(target_os = "linux") { |
115 |
| - message.push_str( |
116 |
| - " |
117 |
| -Linux cross tests target i686-unknown-linux-gnu, which requires the ability to |
118 |
| -build and run 32-bit targets. This requires the 32-bit libraries to be |
119 |
| -installed. For example, on Ubuntu, run `sudo apt install gcc-multilib` to |
120 |
| -install the necessary libraries. |
121 |
| -", |
122 |
| - ); |
123 |
| - } else if cfg!(all(target_os = "macos", target_arch = "aarch64")) { |
124 |
| - message.push_str( |
125 |
| - " |
126 |
| -macOS on aarch64 cross tests to target x86_64-apple-darwin. |
127 |
| -This should be natively supported via Xcode, nothing additional besides the |
128 |
| -rustup target should be needed. |
129 |
| -", |
130 |
| - ); |
131 |
| - } else if cfg!(target_os = "macos") { |
132 |
| - message.push_str( |
133 |
| - " |
134 |
| -macOS on x86_64 cross tests to target x86_64-apple-ios, which requires the iOS |
135 |
| -SDK to be installed. This should be included with Xcode automatically. If you |
136 |
| -are using the Xcode command line tools, you'll need to install the full Xcode |
137 |
| -app (from the Apple App Store), and switch to it with this command: |
138 |
| -
|
139 |
| - sudo xcode-select --switch /Applications/Xcode.app/Contents/Developer |
140 |
| -
|
141 |
| -Some cross-tests want to *run* the executables on the host. These tests will |
142 |
| -be ignored if this is not possible. On macOS, this means you need an iOS |
143 |
| -simulator installed to run these tests. To install a simulator, open Xcode, go |
144 |
| -to preferences > Components, and download the latest iOS simulator. |
145 |
| -", |
146 |
| - ); |
147 |
| - } else if cfg!(target_os = "windows") { |
148 |
| - message.push_str( |
149 |
| - " |
150 |
| -Windows cross tests target i686-pc-windows-msvc, which requires the ability |
151 |
| -to build and run 32-bit targets. This should work automatically if you have |
152 |
| -properly installed Visual Studio build tools. |
153 |
| -", |
154 |
| - ); |
155 |
| - } else { |
156 |
| - // The check at the top should prevent this. |
157 |
| - panic!("platform should have been skipped"); |
158 |
| - } |
159 |
| - |
160 |
| - let rustup_available = Command::new("rustup").output().is_ok(); |
161 |
| - if rustup_available { |
162 |
| - write!( |
163 |
| - message, |
164 |
| - " |
165 |
| -Make sure that the appropriate `rustc` target is installed with rustup: |
166 |
| -
|
167 |
| - rustup target add {} |
168 |
| -", |
169 |
| - cross_target |
170 |
| - ) |
171 |
| - .unwrap(); |
172 |
| - } else { |
173 |
| - write!( |
174 |
| - message, |
175 |
| - " |
176 |
| -rustup does not appear to be installed. Make sure that the appropriate |
177 |
| -`rustc` target is installed for the target `{}`. |
178 |
| -", |
179 |
| - cross_target |
180 |
| - ) |
181 |
| - .unwrap(); |
182 |
| - } |
183 |
| - |
184 |
| - // Show the actual error message. |
185 |
| - match run_cross_test() { |
186 |
| - Ok(_) => message.push_str("\nUh oh, second run succeeded?\n"), |
187 |
| - Err(err) => match err.downcast_ref::<ProcessError>() { |
188 |
| - Some(proc_err) => write!(message, "\nTest error: {}\n", proc_err).unwrap(), |
189 |
| - None => write!(message, "\nUnexpected non-process error: {}\n", err).unwrap(), |
190 |
| - }, |
191 |
| - } |
192 |
| - |
193 |
| - panic!("{}", message); |
194 |
| -} |
195 | 13 |
|
196 | 14 | /// The arch triple of the test-running host.
|
197 | 15 | pub fn native() -> &'static str {
|
@@ -252,31 +70,9 @@ pub fn unused() -> &'static str {
|
252 | 70 | "wasm32-unknown-unknown"
|
253 | 71 | }
|
254 | 72 |
|
255 |
| -/// Whether or not the host can run cross-compiled executables. |
256 |
| -pub fn can_run_on_host() -> bool { |
257 |
| - if disabled() { |
258 |
| - return false; |
259 |
| - } |
260 |
| - // macos is currently configured to cross compile to x86_64-apple-ios |
261 |
| - // which requires a simulator to run. Azure's CI image appears to have the |
262 |
| - // SDK installed, but are not configured to launch iOS images with a |
263 |
| - // simulator. |
264 |
| - if cfg!(target_os = "macos") { |
265 |
| - if CAN_RUN_ON_HOST.load(Ordering::SeqCst) { |
266 |
| - return true; |
267 |
| - } else { |
268 |
| - println!("Note: Cannot run on host, skipping."); |
269 |
| - return false; |
270 |
| - } |
271 |
| - } else { |
272 |
| - assert!(CAN_RUN_ON_HOST.load(Ordering::SeqCst)); |
273 |
| - return true; |
274 |
| - } |
275 |
| -} |
276 |
| - |
277 | 73 | /// Check if the given target has been installed.
|
278 | 74 | ///
|
279 |
| -/// Generally [`disabled`] should be used to check if cross-compilation is allowed. |
| 75 | +/// Generally `testsuite::utils::cross_compile::disabled` should be used to check if cross-compilation is allowed. |
280 | 76 | /// And [`alternate`] to get the cross target.
|
281 | 77 | ///
|
282 | 78 | /// You should only use this as a last resort to skip tests,
|
|
0 commit comments