]>
Commit | Line | Data |
---|---|---|
f2b60f7d FG |
1 | use super::build_sysroot; |
2 | use super::config; | |
9c376795 FG |
3 | use super::path::{Dirs, RelPath}; |
4 | use super::prepare::GitRepo; | |
5 | use super::rustc_info::{get_cargo_path, get_wrapper_file_name}; | |
6 | use super::utils::{ | |
7 | hyperfine_command, spawn_and_wait, spawn_and_wait_with_input, CargoProject, Compiler, | |
8 | }; | |
9 | use super::SysrootKind; | |
f2b60f7d FG |
10 | use std::env; |
11 | use std::ffi::OsStr; | |
12 | use std::fs; | |
9c376795 | 13 | use std::path::Path; |
f2b60f7d FG |
14 | use std::process::Command; |
15 | ||
9c376795 FG |
16 | static BUILD_EXAMPLE_OUT_DIR: RelPath = RelPath::BUILD.join("example"); |
17 | ||
f2b60f7d FG |
18 | struct TestCase { |
19 | config: &'static str, | |
20 | func: &'static dyn Fn(&TestRunner), | |
21 | } | |
22 | ||
23 | impl TestCase { | |
24 | const fn new(config: &'static str, func: &'static dyn Fn(&TestRunner)) -> Self { | |
25 | Self { config, func } | |
26 | } | |
27 | } | |
28 | ||
29 | const NO_SYSROOT_SUITE: &[TestCase] = &[ | |
30 | TestCase::new("build.mini_core", &|runner| { | |
31 | runner.run_rustc([ | |
32 | "example/mini_core.rs", | |
33 | "--crate-name", | |
34 | "mini_core", | |
35 | "--crate-type", | |
36 | "lib,dylib", | |
37 | "--target", | |
9c376795 | 38 | &runner.target_compiler.triple, |
f2b60f7d FG |
39 | ]); |
40 | }), | |
41 | TestCase::new("build.example", &|runner| { | |
42 | runner.run_rustc([ | |
43 | "example/example.rs", | |
44 | "--crate-type", | |
45 | "lib", | |
46 | "--target", | |
9c376795 | 47 | &runner.target_compiler.triple, |
f2b60f7d FG |
48 | ]); |
49 | }), | |
50 | TestCase::new("jit.mini_core_hello_world", &|runner| { | |
51 | let mut jit_cmd = runner.rustc_command([ | |
52 | "-Zunstable-options", | |
53 | "-Cllvm-args=mode=jit", | |
54 | "-Cprefer-dynamic", | |
55 | "example/mini_core_hello_world.rs", | |
56 | "--cfg", | |
57 | "jit", | |
58 | "--target", | |
9c376795 | 59 | &runner.target_compiler.triple, |
f2b60f7d FG |
60 | ]); |
61 | jit_cmd.env("CG_CLIF_JIT_ARGS", "abc bcd"); | |
62 | spawn_and_wait(jit_cmd); | |
63 | ||
64 | eprintln!("[JIT-lazy] mini_core_hello_world"); | |
65 | let mut jit_cmd = runner.rustc_command([ | |
66 | "-Zunstable-options", | |
67 | "-Cllvm-args=mode=jit-lazy", | |
68 | "-Cprefer-dynamic", | |
69 | "example/mini_core_hello_world.rs", | |
70 | "--cfg", | |
71 | "jit", | |
72 | "--target", | |
9c376795 | 73 | &runner.target_compiler.triple, |
f2b60f7d FG |
74 | ]); |
75 | jit_cmd.env("CG_CLIF_JIT_ARGS", "abc bcd"); | |
76 | spawn_and_wait(jit_cmd); | |
77 | }), | |
78 | TestCase::new("aot.mini_core_hello_world", &|runner| { | |
79 | runner.run_rustc([ | |
80 | "example/mini_core_hello_world.rs", | |
81 | "--crate-name", | |
82 | "mini_core_hello_world", | |
83 | "--crate-type", | |
84 | "bin", | |
85 | "-g", | |
86 | "--target", | |
9c376795 | 87 | &runner.target_compiler.triple, |
f2b60f7d FG |
88 | ]); |
89 | runner.run_out_command("mini_core_hello_world", ["abc", "bcd"]); | |
90 | }), | |
91 | ]; | |
92 | ||
93 | const BASE_SYSROOT_SUITE: &[TestCase] = &[ | |
94 | TestCase::new("aot.arbitrary_self_types_pointers_and_wrappers", &|runner| { | |
95 | runner.run_rustc([ | |
96 | "example/arbitrary_self_types_pointers_and_wrappers.rs", | |
97 | "--crate-name", | |
98 | "arbitrary_self_types_pointers_and_wrappers", | |
99 | "--crate-type", | |
100 | "bin", | |
101 | "--target", | |
9c376795 | 102 | &runner.target_compiler.triple, |
f2b60f7d FG |
103 | ]); |
104 | runner.run_out_command("arbitrary_self_types_pointers_and_wrappers", []); | |
105 | }), | |
106 | TestCase::new("aot.issue_91827_extern_types", &|runner| { | |
107 | runner.run_rustc([ | |
108 | "example/issue-91827-extern-types.rs", | |
109 | "--crate-name", | |
110 | "issue_91827_extern_types", | |
111 | "--crate-type", | |
112 | "bin", | |
113 | "--target", | |
9c376795 | 114 | &runner.target_compiler.triple, |
f2b60f7d FG |
115 | ]); |
116 | runner.run_out_command("issue_91827_extern_types", []); | |
117 | }), | |
118 | TestCase::new("build.alloc_system", &|runner| { | |
119 | runner.run_rustc([ | |
120 | "example/alloc_system.rs", | |
121 | "--crate-type", | |
122 | "lib", | |
123 | "--target", | |
9c376795 | 124 | &runner.target_compiler.triple, |
f2b60f7d FG |
125 | ]); |
126 | }), | |
127 | TestCase::new("aot.alloc_example", &|runner| { | |
128 | runner.run_rustc([ | |
129 | "example/alloc_example.rs", | |
130 | "--crate-type", | |
131 | "bin", | |
132 | "--target", | |
9c376795 | 133 | &runner.target_compiler.triple, |
f2b60f7d FG |
134 | ]); |
135 | runner.run_out_command("alloc_example", []); | |
136 | }), | |
137 | TestCase::new("jit.std_example", &|runner| { | |
138 | runner.run_rustc([ | |
139 | "-Zunstable-options", | |
140 | "-Cllvm-args=mode=jit", | |
141 | "-Cprefer-dynamic", | |
142 | "example/std_example.rs", | |
143 | "--target", | |
9c376795 | 144 | &runner.target_compiler.triple, |
f2b60f7d FG |
145 | ]); |
146 | ||
147 | eprintln!("[JIT-lazy] std_example"); | |
148 | runner.run_rustc([ | |
149 | "-Zunstable-options", | |
150 | "-Cllvm-args=mode=jit-lazy", | |
151 | "-Cprefer-dynamic", | |
152 | "example/std_example.rs", | |
153 | "--target", | |
9c376795 | 154 | &runner.target_compiler.triple, |
f2b60f7d FG |
155 | ]); |
156 | }), | |
157 | TestCase::new("aot.std_example", &|runner| { | |
158 | runner.run_rustc([ | |
159 | "example/std_example.rs", | |
160 | "--crate-type", | |
161 | "bin", | |
162 | "--target", | |
9c376795 | 163 | &runner.target_compiler.triple, |
f2b60f7d FG |
164 | ]); |
165 | runner.run_out_command("std_example", ["arg"]); | |
166 | }), | |
167 | TestCase::new("aot.dst_field_align", &|runner| { | |
168 | runner.run_rustc([ | |
169 | "example/dst-field-align.rs", | |
170 | "--crate-name", | |
171 | "dst_field_align", | |
172 | "--crate-type", | |
173 | "bin", | |
174 | "--target", | |
9c376795 | 175 | &runner.target_compiler.triple, |
f2b60f7d FG |
176 | ]); |
177 | runner.run_out_command("dst_field_align", []); | |
178 | }), | |
179 | TestCase::new("aot.subslice-patterns-const-eval", &|runner| { | |
180 | runner.run_rustc([ | |
181 | "example/subslice-patterns-const-eval.rs", | |
182 | "--crate-type", | |
183 | "bin", | |
184 | "-Cpanic=abort", | |
185 | "--target", | |
9c376795 | 186 | &runner.target_compiler.triple, |
f2b60f7d FG |
187 | ]); |
188 | runner.run_out_command("subslice-patterns-const-eval", []); | |
189 | }), | |
190 | TestCase::new("aot.track-caller-attribute", &|runner| { | |
191 | runner.run_rustc([ | |
192 | "example/track-caller-attribute.rs", | |
193 | "--crate-type", | |
194 | "bin", | |
195 | "-Cpanic=abort", | |
196 | "--target", | |
9c376795 | 197 | &runner.target_compiler.triple, |
f2b60f7d FG |
198 | ]); |
199 | runner.run_out_command("track-caller-attribute", []); | |
200 | }), | |
201 | TestCase::new("aot.float-minmax-pass", &|runner| { | |
202 | runner.run_rustc([ | |
203 | "example/float-minmax-pass.rs", | |
204 | "--crate-type", | |
205 | "bin", | |
206 | "-Cpanic=abort", | |
207 | "--target", | |
9c376795 | 208 | &runner.target_compiler.triple, |
f2b60f7d FG |
209 | ]); |
210 | runner.run_out_command("float-minmax-pass", []); | |
211 | }), | |
212 | TestCase::new("aot.mod_bench", &|runner| { | |
213 | runner.run_rustc([ | |
214 | "example/mod_bench.rs", | |
215 | "--crate-type", | |
216 | "bin", | |
217 | "--target", | |
9c376795 | 218 | &runner.target_compiler.triple, |
f2b60f7d FG |
219 | ]); |
220 | runner.run_out_command("mod_bench", []); | |
221 | }), | |
9c376795 FG |
222 | TestCase::new("aot.issue-72793", &|runner| { |
223 | runner.run_rustc([ | |
224 | "example/issue-72793.rs", | |
225 | "--crate-type", | |
226 | "bin", | |
227 | "--target", | |
228 | &runner.target_compiler.triple, | |
229 | ]); | |
230 | runner.run_out_command("issue-72793", []); | |
231 | }), | |
f2b60f7d FG |
232 | ]; |
233 | ||
9c376795 FG |
234 | pub(crate) static RAND_REPO: GitRepo = |
235 | GitRepo::github("rust-random", "rand", "0f933f9c7176e53b2a3c7952ded484e1783f0bf1", "rand"); | |
236 | ||
237 | static RAND: CargoProject = CargoProject::new(&RAND_REPO.source_dir(), "rand"); | |
238 | ||
239 | pub(crate) static REGEX_REPO: GitRepo = | |
240 | GitRepo::github("rust-lang", "regex", "341f207c1071f7290e3f228c710817c280c8dca1", "regex"); | |
241 | ||
242 | static REGEX: CargoProject = CargoProject::new(®EX_REPO.source_dir(), "regex"); | |
243 | ||
244 | pub(crate) static PORTABLE_SIMD_REPO: GitRepo = GitRepo::github( | |
245 | "rust-lang", | |
246 | "portable-simd", | |
247 | "d5cd4a8112d958bd3a252327e0d069a6363249bd", | |
248 | "portable-simd", | |
249 | ); | |
250 | ||
251 | static PORTABLE_SIMD: CargoProject = | |
252 | CargoProject::new(&PORTABLE_SIMD_REPO.source_dir(), "portable_simd"); | |
253 | ||
254 | pub(crate) static SIMPLE_RAYTRACER_REPO: GitRepo = GitRepo::github( | |
255 | "ebobby", | |
256 | "simple-raytracer", | |
257 | "804a7a21b9e673a482797aa289a18ed480e4d813", | |
258 | "<none>", | |
259 | ); | |
260 | ||
261 | pub(crate) static SIMPLE_RAYTRACER: CargoProject = | |
262 | CargoProject::new(&SIMPLE_RAYTRACER_REPO.source_dir(), "simple_raytracer"); | |
263 | ||
264 | static LIBCORE_TESTS: CargoProject = | |
265 | CargoProject::new(&RelPath::BUILD_SYSROOT.join("sysroot_src/library/core/tests"), "core_tests"); | |
266 | ||
f2b60f7d FG |
267 | const EXTENDED_SYSROOT_SUITE: &[TestCase] = &[ |
268 | TestCase::new("test.rust-random/rand", &|runner| { | |
9c376795 FG |
269 | spawn_and_wait(RAND.clean(&runner.target_compiler.cargo, &runner.dirs)); |
270 | ||
271 | if runner.is_native { | |
272 | eprintln!("[TEST] rust-random/rand"); | |
273 | let mut test_cmd = RAND.test(&runner.target_compiler, &runner.dirs); | |
274 | test_cmd.arg("--workspace"); | |
275 | spawn_and_wait(test_cmd); | |
276 | } else { | |
277 | eprintln!("[AOT] rust-random/rand"); | |
278 | let mut build_cmd = RAND.build(&runner.target_compiler, &runner.dirs); | |
279 | build_cmd.arg("--workspace").arg("--tests"); | |
280 | spawn_and_wait(build_cmd); | |
281 | } | |
f2b60f7d FG |
282 | }), |
283 | TestCase::new("bench.simple-raytracer", &|runner| { | |
9c376795 FG |
284 | let run_runs = env::var("RUN_RUNS").unwrap_or("10".to_string()).parse().unwrap(); |
285 | ||
286 | if runner.is_native { | |
287 | eprintln!("[BENCH COMPILE] ebobby/simple-raytracer"); | |
288 | let cargo_clif = RelPath::DIST | |
289 | .to_path(&runner.dirs) | |
290 | .join(get_wrapper_file_name("cargo-clif", "bin")); | |
291 | let manifest_path = SIMPLE_RAYTRACER.manifest_path(&runner.dirs); | |
292 | let target_dir = SIMPLE_RAYTRACER.target_dir(&runner.dirs); | |
293 | ||
294 | let clean_cmd = format!( | |
295 | "cargo clean --manifest-path {manifest_path} --target-dir {target_dir}", | |
296 | manifest_path = manifest_path.display(), | |
297 | target_dir = target_dir.display(), | |
298 | ); | |
299 | let llvm_build_cmd = format!( | |
300 | "cargo build --manifest-path {manifest_path} --target-dir {target_dir}", | |
301 | manifest_path = manifest_path.display(), | |
302 | target_dir = target_dir.display(), | |
303 | ); | |
304 | let clif_build_cmd = format!( | |
305 | "{cargo_clif} build --manifest-path {manifest_path} --target-dir {target_dir}", | |
306 | cargo_clif = cargo_clif.display(), | |
307 | manifest_path = manifest_path.display(), | |
308 | target_dir = target_dir.display(), | |
309 | ); | |
310 | ||
311 | let bench_compile = | |
312 | hyperfine_command(1, run_runs, Some(&clean_cmd), &llvm_build_cmd, &clif_build_cmd); | |
313 | ||
314 | spawn_and_wait(bench_compile); | |
315 | ||
316 | eprintln!("[BENCH RUN] ebobby/simple-raytracer"); | |
317 | fs::copy( | |
318 | target_dir.join("debug").join("main"), | |
319 | RelPath::BUILD.to_path(&runner.dirs).join("raytracer_cg_clif"), | |
320 | ) | |
321 | .unwrap(); | |
322 | ||
323 | let mut bench_run = | |
324 | hyperfine_command(0, run_runs, None, "./raytracer_cg_llvm", "./raytracer_cg_clif"); | |
325 | bench_run.current_dir(RelPath::BUILD.to_path(&runner.dirs)); | |
326 | spawn_and_wait(bench_run); | |
327 | } else { | |
328 | spawn_and_wait(SIMPLE_RAYTRACER.clean(&runner.target_compiler.cargo, &runner.dirs)); | |
329 | eprintln!("[BENCH COMPILE] ebobby/simple-raytracer (skipped)"); | |
330 | eprintln!("[COMPILE] ebobby/simple-raytracer"); | |
331 | spawn_and_wait(SIMPLE_RAYTRACER.build(&runner.target_compiler, &runner.dirs)); | |
332 | eprintln!("[BENCH RUN] ebobby/simple-raytracer (skipped)"); | |
333 | } | |
f2b60f7d FG |
334 | }), |
335 | TestCase::new("test.libcore", &|runner| { | |
9c376795 FG |
336 | spawn_and_wait(LIBCORE_TESTS.clean(&runner.host_compiler.cargo, &runner.dirs)); |
337 | ||
338 | if runner.is_native { | |
339 | spawn_and_wait(LIBCORE_TESTS.test(&runner.target_compiler, &runner.dirs)); | |
340 | } else { | |
341 | eprintln!("Cross-Compiling: Not running tests"); | |
342 | let mut build_cmd = LIBCORE_TESTS.build(&runner.target_compiler, &runner.dirs); | |
343 | build_cmd.arg("--tests"); | |
344 | spawn_and_wait(build_cmd); | |
345 | } | |
f2b60f7d FG |
346 | }), |
347 | TestCase::new("test.regex-shootout-regex-dna", &|runner| { | |
9c376795 FG |
348 | spawn_and_wait(REGEX.clean(&runner.target_compiler.cargo, &runner.dirs)); |
349 | ||
350 | // newer aho_corasick versions throw a deprecation warning | |
351 | let lint_rust_flags = format!("{} --cap-lints warn", runner.target_compiler.rustflags); | |
352 | ||
353 | let mut build_cmd = REGEX.build(&runner.target_compiler, &runner.dirs); | |
354 | build_cmd.arg("--example").arg("shootout-regex-dna"); | |
355 | build_cmd.env("RUSTFLAGS", lint_rust_flags.clone()); | |
356 | spawn_and_wait(build_cmd); | |
357 | ||
358 | if runner.is_native { | |
359 | let mut run_cmd = REGEX.run(&runner.target_compiler, &runner.dirs); | |
360 | run_cmd.arg("--example").arg("shootout-regex-dna"); | |
361 | run_cmd.env("RUSTFLAGS", lint_rust_flags); | |
362 | ||
363 | let input = fs::read_to_string( | |
364 | REGEX.source_dir(&runner.dirs).join("examples").join("regexdna-input.txt"), | |
365 | ) | |
366 | .unwrap(); | |
367 | let expected_path = | |
368 | REGEX.source_dir(&runner.dirs).join("examples").join("regexdna-output.txt"); | |
369 | let expected = fs::read_to_string(&expected_path).unwrap(); | |
370 | ||
371 | let output = spawn_and_wait_with_input(run_cmd, input); | |
372 | // Make sure `[codegen mono items] start` doesn't poison the diff | |
373 | let output = output | |
374 | .lines() | |
375 | .filter(|line| !line.contains("codegen mono items")) | |
376 | .chain(Some("")) // This just adds the trailing newline | |
377 | .collect::<Vec<&str>>() | |
378 | .join("\r\n"); | |
379 | ||
380 | let output_matches = expected.lines().eq(output.lines()); | |
381 | if !output_matches { | |
382 | let res_path = REGEX.source_dir(&runner.dirs).join("res.txt"); | |
383 | fs::write(&res_path, &output).unwrap(); | |
384 | ||
385 | if cfg!(windows) { | |
386 | println!("Output files don't match!"); | |
387 | println!("Expected Output:\n{}", expected); | |
388 | println!("Actual Output:\n{}", output); | |
389 | } else { | |
390 | let mut diff = Command::new("diff"); | |
391 | diff.arg("-u"); | |
392 | diff.arg(res_path); | |
393 | diff.arg(expected_path); | |
394 | spawn_and_wait(diff); | |
f2b60f7d | 395 | } |
9c376795 FG |
396 | |
397 | std::process::exit(1); | |
f2b60f7d | 398 | } |
9c376795 | 399 | } |
f2b60f7d FG |
400 | }), |
401 | TestCase::new("test.regex", &|runner| { | |
9c376795 FG |
402 | spawn_and_wait(REGEX.clean(&runner.host_compiler.cargo, &runner.dirs)); |
403 | ||
404 | // newer aho_corasick versions throw a deprecation warning | |
405 | let lint_rust_flags = format!("{} --cap-lints warn", runner.target_compiler.rustflags); | |
406 | ||
407 | if runner.is_native { | |
408 | let mut run_cmd = REGEX.test(&runner.target_compiler, &runner.dirs); | |
409 | run_cmd.args([ | |
410 | "--tests", | |
411 | "--", | |
412 | "--exclude-should-panic", | |
413 | "--test-threads", | |
414 | "1", | |
415 | "-Zunstable-options", | |
416 | "-q", | |
417 | ]); | |
418 | run_cmd.env("RUSTFLAGS", lint_rust_flags); | |
419 | spawn_and_wait(run_cmd); | |
420 | } else { | |
421 | eprintln!("Cross-Compiling: Not running tests"); | |
422 | let mut build_cmd = REGEX.build(&runner.target_compiler, &runner.dirs); | |
423 | build_cmd.arg("--tests"); | |
424 | build_cmd.env("RUSTFLAGS", lint_rust_flags.clone()); | |
425 | spawn_and_wait(build_cmd); | |
426 | } | |
f2b60f7d FG |
427 | }), |
428 | TestCase::new("test.portable-simd", &|runner| { | |
9c376795 | 429 | spawn_and_wait(PORTABLE_SIMD.clean(&runner.host_compiler.cargo, &runner.dirs)); |
f2b60f7d | 430 | |
9c376795 FG |
431 | let mut build_cmd = PORTABLE_SIMD.build(&runner.target_compiler, &runner.dirs); |
432 | build_cmd.arg("--all-targets"); | |
433 | spawn_and_wait(build_cmd); | |
434 | ||
435 | if runner.is_native { | |
436 | let mut test_cmd = PORTABLE_SIMD.test(&runner.target_compiler, &runner.dirs); | |
437 | test_cmd.arg("-q"); | |
438 | spawn_and_wait(test_cmd); | |
439 | } | |
f2b60f7d FG |
440 | }), |
441 | ]; | |
442 | ||
443 | pub(crate) fn run_tests( | |
9c376795 | 444 | dirs: &Dirs, |
f2b60f7d FG |
445 | channel: &str, |
446 | sysroot_kind: SysrootKind, | |
2b03887a | 447 | cg_clif_dylib: &Path, |
f2b60f7d FG |
448 | host_triple: &str, |
449 | target_triple: &str, | |
450 | ) { | |
9c376795 | 451 | let runner = TestRunner::new(dirs.clone(), host_triple.to_string(), target_triple.to_string()); |
f2b60f7d FG |
452 | |
453 | if config::get_bool("testsuite.no_sysroot") { | |
454 | build_sysroot::build_sysroot( | |
9c376795 | 455 | dirs, |
f2b60f7d FG |
456 | channel, |
457 | SysrootKind::None, | |
2b03887a | 458 | cg_clif_dylib, |
f2b60f7d FG |
459 | &host_triple, |
460 | &target_triple, | |
461 | ); | |
462 | ||
9c376795 | 463 | BUILD_EXAMPLE_OUT_DIR.ensure_fresh(dirs); |
f2b60f7d FG |
464 | runner.run_testsuite(NO_SYSROOT_SUITE); |
465 | } else { | |
466 | eprintln!("[SKIP] no_sysroot tests"); | |
467 | } | |
468 | ||
469 | let run_base_sysroot = config::get_bool("testsuite.base_sysroot"); | |
470 | let run_extended_sysroot = config::get_bool("testsuite.extended_sysroot"); | |
471 | ||
472 | if run_base_sysroot || run_extended_sysroot { | |
473 | build_sysroot::build_sysroot( | |
9c376795 | 474 | dirs, |
f2b60f7d FG |
475 | channel, |
476 | sysroot_kind, | |
2b03887a | 477 | cg_clif_dylib, |
f2b60f7d FG |
478 | &host_triple, |
479 | &target_triple, | |
480 | ); | |
481 | } | |
482 | ||
483 | if run_base_sysroot { | |
484 | runner.run_testsuite(BASE_SYSROOT_SUITE); | |
485 | } else { | |
486 | eprintln!("[SKIP] base_sysroot tests"); | |
487 | } | |
488 | ||
489 | if run_extended_sysroot { | |
490 | runner.run_testsuite(EXTENDED_SYSROOT_SUITE); | |
491 | } else { | |
492 | eprintln!("[SKIP] extended_sysroot tests"); | |
493 | } | |
494 | } | |
495 | ||
496 | struct TestRunner { | |
9c376795 | 497 | is_native: bool, |
f2b60f7d | 498 | jit_supported: bool, |
9c376795 FG |
499 | dirs: Dirs, |
500 | host_compiler: Compiler, | |
501 | target_compiler: Compiler, | |
f2b60f7d FG |
502 | } |
503 | ||
504 | impl TestRunner { | |
9c376795 | 505 | pub fn new(dirs: Dirs, host_triple: String, target_triple: String) -> Self { |
f2b60f7d FG |
506 | let is_native = host_triple == target_triple; |
507 | let jit_supported = | |
508 | target_triple.contains("x86_64") && is_native && !host_triple.contains("windows"); | |
509 | ||
9c376795 FG |
510 | let rustc_clif = |
511 | RelPath::DIST.to_path(&dirs).join(get_wrapper_file_name("rustc-clif", "bin")); | |
512 | let rustdoc_clif = | |
513 | RelPath::DIST.to_path(&dirs).join(get_wrapper_file_name("rustdoc-clif", "bin")); | |
514 | ||
515 | let mut rustflags = env::var("RUSTFLAGS").ok().unwrap_or("".to_string()); | |
516 | let mut runner = vec![]; | |
f2b60f7d FG |
517 | |
518 | if !is_native { | |
519 | match target_triple.as_str() { | |
520 | "aarch64-unknown-linux-gnu" => { | |
521 | // We are cross-compiling for aarch64. Use the correct linker and run tests in qemu. | |
9c376795 FG |
522 | rustflags = format!("-Clinker=aarch64-linux-gnu-gcc{}", rustflags); |
523 | runner = vec![ | |
524 | "qemu-aarch64".to_owned(), | |
525 | "-L".to_owned(), | |
526 | "/usr/aarch64-linux-gnu".to_owned(), | |
527 | ]; | |
528 | } | |
529 | "s390x-unknown-linux-gnu" => { | |
530 | // We are cross-compiling for s390x. Use the correct linker and run tests in qemu. | |
531 | rustflags = format!("-Clinker=s390x-linux-gnu-gcc{}", rustflags); | |
532 | runner = vec![ | |
533 | "qemu-s390x".to_owned(), | |
534 | "-L".to_owned(), | |
535 | "/usr/s390x-linux-gnu".to_owned(), | |
536 | ]; | |
f2b60f7d FG |
537 | } |
538 | "x86_64-pc-windows-gnu" => { | |
539 | // We are cross-compiling for Windows. Run tests in wine. | |
9c376795 | 540 | runner = vec!["wine".to_owned()]; |
f2b60f7d FG |
541 | } |
542 | _ => { | |
543 | println!("Unknown non-native platform"); | |
544 | } | |
545 | } | |
546 | } | |
547 | ||
548 | // FIXME fix `#[linkage = "extern_weak"]` without this | |
9c376795 FG |
549 | if target_triple.contains("darwin") { |
550 | rustflags = format!("{} -Clink-arg=-undefined -Clink-arg=dynamic_lookup", rustflags); | |
f2b60f7d FG |
551 | } |
552 | ||
9c376795 FG |
553 | let host_compiler = Compiler { |
554 | cargo: get_cargo_path(), | |
555 | rustc: rustc_clif.clone(), | |
556 | rustdoc: rustdoc_clif.clone(), | |
557 | rustflags: String::new(), | |
558 | rustdocflags: String::new(), | |
559 | triple: host_triple, | |
560 | runner: vec![], | |
561 | }; | |
562 | ||
563 | let target_compiler = Compiler { | |
564 | cargo: get_cargo_path(), | |
565 | rustc: rustc_clif, | |
566 | rustdoc: rustdoc_clif, | |
567 | rustflags: rustflags.clone(), | |
568 | rustdocflags: rustflags, | |
569 | triple: target_triple, | |
570 | runner, | |
571 | }; | |
572 | ||
573 | Self { is_native, jit_supported, dirs, host_compiler, target_compiler } | |
f2b60f7d FG |
574 | } |
575 | ||
576 | pub fn run_testsuite(&self, tests: &[TestCase]) { | |
577 | for &TestCase { config, func } in tests { | |
578 | let (tag, testname) = config.split_once('.').unwrap(); | |
579 | let tag = tag.to_uppercase(); | |
580 | let is_jit_test = tag == "JIT"; | |
581 | ||
582 | if !config::get_bool(config) || (is_jit_test && !self.jit_supported) { | |
583 | eprintln!("[{tag}] {testname} (skipped)"); | |
584 | continue; | |
585 | } else { | |
586 | eprintln!("[{tag}] {testname}"); | |
587 | } | |
588 | ||
589 | func(self); | |
590 | } | |
591 | } | |
592 | ||
9c376795 | 593 | #[must_use] |
f2b60f7d FG |
594 | fn rustc_command<I, S>(&self, args: I) -> Command |
595 | where | |
596 | I: IntoIterator<Item = S>, | |
597 | S: AsRef<OsStr>, | |
598 | { | |
9c376795 FG |
599 | let mut cmd = Command::new(&self.target_compiler.rustc); |
600 | cmd.args(self.target_compiler.rustflags.split_whitespace()); | |
f2b60f7d | 601 | cmd.arg("-L"); |
9c376795 | 602 | cmd.arg(format!("crate={}", BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs).display())); |
f2b60f7d | 603 | cmd.arg("--out-dir"); |
9c376795 | 604 | cmd.arg(format!("{}", BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs).display())); |
f2b60f7d FG |
605 | cmd.arg("-Cdebuginfo=2"); |
606 | cmd.args(args); | |
607 | cmd | |
608 | } | |
609 | ||
610 | fn run_rustc<I, S>(&self, args: I) | |
611 | where | |
612 | I: IntoIterator<Item = S>, | |
613 | S: AsRef<OsStr>, | |
614 | { | |
615 | spawn_and_wait(self.rustc_command(args)); | |
616 | } | |
617 | ||
618 | fn run_out_command<'a, I>(&self, name: &str, args: I) | |
619 | where | |
620 | I: IntoIterator<Item = &'a str>, | |
621 | { | |
622 | let mut full_cmd = vec![]; | |
623 | ||
624 | // Prepend the RUN_WRAPPER's | |
9c376795 FG |
625 | if !self.target_compiler.runner.is_empty() { |
626 | full_cmd.extend(self.target_compiler.runner.iter().cloned()); | |
f2b60f7d FG |
627 | } |
628 | ||
9c376795 FG |
629 | full_cmd.push( |
630 | BUILD_EXAMPLE_OUT_DIR.to_path(&self.dirs).join(name).to_str().unwrap().to_string(), | |
631 | ); | |
f2b60f7d FG |
632 | |
633 | for arg in args.into_iter() { | |
634 | full_cmd.push(arg.to_string()); | |
635 | } | |
636 | ||
637 | let mut cmd_iter = full_cmd.into_iter(); | |
638 | let first = cmd_iter.next().unwrap(); | |
639 | ||
640 | let mut cmd = Command::new(first); | |
641 | cmd.args(cmd_iter); | |
642 | ||
643 | spawn_and_wait(cmd); | |
644 | } | |
f2b60f7d | 645 | } |