2 use crate::config::{Config, TargetSelection};
5 fn configure(cmd: &str, host: &[&str], target: &[&str]) -> Config {
6 let mut config = Config::parse(&[cmd.to_owned()]);
7 // don't save toolstates
8 config.save_toolstates = None;
10 config.ninja_in_file = false;
11 // try to avoid spurious failures in dist where we create/delete each others file
12 config.out = PathBuf::from(env::var_os("BOOTSTRAP_OUTPUT_DIRECTORY").unwrap());
13 config.initial_rustc = PathBuf::from(env::var_os("RUSTC").unwrap());
14 config.initial_cargo = PathBuf::from(env::var_os("BOOTSTRAP_INITIAL_CARGO").unwrap());
17 .join("tmp-rustbuild-tests")
18 .join(&thread::current().name().unwrap_or("unknown").replace(":", "-"));
19 t!(fs::create_dir_all(&dir));
21 config.build = TargetSelection::from_user("A");
22 config.hosts = host.iter().map(|s| TargetSelection::from_user(s)).collect();
23 config.targets = target.iter().map(|s| TargetSelection::from_user(s)).collect();
27 fn first<A, B>(v: Vec<(A, B)>) -> Vec<A> {
28 v.into_iter().map(|(a, _)| a).collect::<Vec<_>>()
32 use super::{configure, first};
33 use crate::builder::*;
35 use pretty_assertions::assert_eq;
39 let build = Build::new(configure("build", &["A"], &["A"]));
40 let mut builder = Builder::new(&build);
41 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]);
43 let a = TargetSelection::from_user("A");
45 first(builder.cache.all::<compile::Std>()),
47 compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
48 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
51 assert!(!builder.cache.all::<compile::Assemble>().is_empty());
52 // Make sure rustdoc is only built once.
54 first(builder.cache.all::<tool::Rustdoc>()),
55 // Recall that rustdoc stages are off-by-one
56 // - this is the compiler it's _linked_ to, not built with.
57 &[tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }],
60 first(builder.cache.all::<compile::Rustc>()),
61 &[compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },]
67 let config = Config { stage: 0, ..configure("build", &["A"], &["A"]) };
68 let build = Build::new(config);
69 let mut builder = Builder::new(&build);
70 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]);
72 let a = TargetSelection::from_user("A");
74 first(builder.cache.all::<compile::Std>()),
75 &[compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },]
77 assert!(!builder.cache.all::<compile::Assemble>().is_empty());
79 first(builder.cache.all::<tool::Rustdoc>()),
80 // This is the beta rustdoc.
81 // Add an assert here to make sure this is the only rustdoc built.
82 &[tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } }],
84 assert!(builder.cache.all::<compile::Rustc>().is_empty());
88 fn build_cross_compile() {
89 let config = Config { stage: 1, ..configure("build", &["A", "B"], &["A", "B"]) };
90 let build = Build::new(config);
91 let mut builder = Builder::new(&build);
92 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]);
94 let a = TargetSelection::from_user("A");
95 let b = TargetSelection::from_user("B");
97 // Ideally, this build wouldn't actually have `target: a`
98 // rustdoc/rustcc/std here (the user only requested a host=B build, so
99 // there's not really a need for us to build for target A in this case
100 // (since we're producing stage 1 libraries/binaries). But currently
101 // rustbuild is just a bit buggy here; this should be fixed though.
103 first(builder.cache.all::<compile::Std>()),
105 compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
106 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
107 compile::Std { compiler: Compiler { host: a, stage: 0 }, target: b },
108 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
112 first(builder.cache.all::<compile::Assemble>()),
114 compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
115 compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
116 compile::Assemble { target_compiler: Compiler { host: b, stage: 1 } },
120 first(builder.cache.all::<tool::Rustdoc>()),
122 tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } },
123 tool::Rustdoc { compiler: Compiler { host: b, stage: 1 } },
127 first(builder.cache.all::<compile::Rustc>()),
129 compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },
130 compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: b },
137 let mut config = configure("doc", &["A"], &["A"]);
138 config.compiler_docs = true;
139 config.cmd = Subcommand::Doc { paths: Vec::new(), open: false };
140 let build = Build::new(config);
141 let mut builder = Builder::new(&build);
142 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), &[]);
143 let a = TargetSelection::from_user("A");
145 // error_index_generator uses stage 0 to share rustdoc artifacts with the
148 first(builder.cache.all::<doc::ErrorIndex>()),
149 &[doc::ErrorIndex { target: a },]
152 first(builder.cache.all::<tool::ErrorIndex>()),
153 &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 0 } }]
155 // docs should be built with the beta compiler, not with the stage0 artifacts.
156 // recall that rustdoc is off-by-one: `stage` is the compiler rustdoc is _linked_ to,
157 // not the one it was built by.
159 first(builder.cache.all::<tool::Rustdoc>()),
160 &[tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } },]
166 use super::{first, Config};
167 use crate::builder::*;
168 use pretty_assertions::assert_eq;
170 fn configure(host: &[&str], target: &[&str]) -> Config {
171 Config { stage: 2, ..super::configure("dist", host, target) }
176 let build = Build::new(configure(&["A"], &["A"]));
177 let mut builder = Builder::new(&build);
178 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]);
180 let a = TargetSelection::from_user("A");
182 assert_eq!(first(builder.cache.all::<dist::Docs>()), &[dist::Docs { host: a },]);
183 assert_eq!(first(builder.cache.all::<dist::Mingw>()), &[dist::Mingw { host: a },]);
185 first(builder.cache.all::<dist::Rustc>()),
186 &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },]
189 first(builder.cache.all::<dist::Std>()),
190 &[dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },]
192 assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]);
193 // Make sure rustdoc is only built once.
195 first(builder.cache.all::<tool::Rustdoc>()),
196 &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },]
201 fn dist_with_targets() {
202 let build = Build::new(configure(&["A"], &["A", "B"]));
203 let mut builder = Builder::new(&build);
204 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]);
206 let a = TargetSelection::from_user("A");
207 let b = TargetSelection::from_user("B");
210 first(builder.cache.all::<dist::Docs>()),
211 &[dist::Docs { host: a }, dist::Docs { host: b },]
214 first(builder.cache.all::<dist::Mingw>()),
215 &[dist::Mingw { host: a }, dist::Mingw { host: b },]
218 first(builder.cache.all::<dist::Rustc>()),
219 &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },]
222 first(builder.cache.all::<dist::Std>()),
224 dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
225 dist::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
228 assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]);
232 fn dist_with_hosts() {
233 let build = Build::new(configure(&["A", "B"], &["A", "B"]));
234 let mut builder = Builder::new(&build);
235 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]);
237 let a = TargetSelection::from_user("A");
238 let b = TargetSelection::from_user("B");
241 first(builder.cache.all::<dist::Docs>()),
242 &[dist::Docs { host: a }, dist::Docs { host: b },]
245 first(builder.cache.all::<dist::Mingw>()),
246 &[dist::Mingw { host: a }, dist::Mingw { host: b },]
249 first(builder.cache.all::<dist::Rustc>()),
251 dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
252 dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
256 first(builder.cache.all::<dist::Std>()),
258 dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
259 dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
263 first(builder.cache.all::<compile::Std>()),
265 compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
266 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
267 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a },
268 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
269 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
272 assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]);
276 fn dist_only_cross_host() {
277 let a = TargetSelection::from_user("A");
278 let b = TargetSelection::from_user("B");
279 let mut build = Build::new(configure(&["A", "B"], &["A", "B"]));
280 build.config.docs = false;
281 build.config.extended = true;
282 build.hosts = vec![b];
283 let mut builder = Builder::new(&build);
284 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]);
287 first(builder.cache.all::<dist::Rustc>()),
288 &[dist::Rustc { compiler: Compiler { host: b, stage: 2 } },]
291 first(builder.cache.all::<compile::Rustc>()),
293 compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },
294 compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b },
300 fn dist_with_targets_and_hosts() {
301 let build = Build::new(configure(&["A", "B"], &["A", "B", "C"]));
302 let mut builder = Builder::new(&build);
303 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]);
305 let a = TargetSelection::from_user("A");
306 let b = TargetSelection::from_user("B");
307 let c = TargetSelection::from_user("C");
310 first(builder.cache.all::<dist::Docs>()),
311 &[dist::Docs { host: a }, dist::Docs { host: b }, dist::Docs { host: c },]
314 first(builder.cache.all::<dist::Mingw>()),
315 &[dist::Mingw { host: a }, dist::Mingw { host: b }, dist::Mingw { host: c },]
318 first(builder.cache.all::<dist::Rustc>()),
320 dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
321 dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
325 first(builder.cache.all::<dist::Std>()),
327 dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
328 dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
329 dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c },
332 assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]);
336 fn dist_with_empty_host() {
337 let config = configure(&[], &["C"]);
338 let build = Build::new(config);
339 let mut builder = Builder::new(&build);
340 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]);
342 let a = TargetSelection::from_user("A");
343 let c = TargetSelection::from_user("C");
345 assert_eq!(first(builder.cache.all::<dist::Docs>()), &[dist::Docs { host: c },]);
346 assert_eq!(first(builder.cache.all::<dist::Mingw>()), &[dist::Mingw { host: c },]);
348 first(builder.cache.all::<dist::Std>()),
349 &[dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c },]
354 fn dist_with_same_targets_and_hosts() {
355 let build = Build::new(configure(&["A", "B"], &["A", "B"]));
356 let mut builder = Builder::new(&build);
357 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]);
359 let a = TargetSelection::from_user("A");
360 let b = TargetSelection::from_user("B");
363 first(builder.cache.all::<dist::Docs>()),
364 &[dist::Docs { host: a }, dist::Docs { host: b },]
367 first(builder.cache.all::<dist::Mingw>()),
368 &[dist::Mingw { host: a }, dist::Mingw { host: b },]
371 first(builder.cache.all::<dist::Rustc>()),
373 dist::Rustc { compiler: Compiler { host: a, stage: 2 } },
374 dist::Rustc { compiler: Compiler { host: b, stage: 2 } },
378 first(builder.cache.all::<dist::Std>()),
380 dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
381 dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
384 assert_eq!(first(builder.cache.all::<dist::Src>()), &[dist::Src]);
386 first(builder.cache.all::<compile::Std>()),
388 compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
389 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
390 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a },
391 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
392 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
396 first(builder.cache.all::<compile::Assemble>()),
398 compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
399 compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
400 compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } },
401 compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } },
408 let build = Build::new(configure(&["A", "B"], &["A", "B", "C"]));
409 let mut builder = Builder::new(&build);
410 builder.run_step_descriptions(
411 &Builder::get_step_descriptions(Kind::Build),
412 &["compiler/rustc".into(), "library/std".into()],
415 let a = TargetSelection::from_user("A");
416 let b = TargetSelection::from_user("B");
417 let c = TargetSelection::from_user("C");
420 first(builder.cache.all::<compile::Std>()),
422 compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
423 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
424 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a },
425 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b },
426 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b },
427 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c },
430 assert!(!builder.cache.all::<compile::Assemble>().is_empty());
432 first(builder.cache.all::<compile::Rustc>()),
434 compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },
435 compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a },
436 compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: a },
437 compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b },
438 compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: b },
444 fn build_with_empty_host() {
445 let config = configure(&[], &["C"]);
446 let build = Build::new(config);
447 let mut builder = Builder::new(&build);
448 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]);
450 let a = TargetSelection::from_user("A");
451 let c = TargetSelection::from_user("C");
454 first(builder.cache.all::<compile::Std>()),
456 compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },
457 compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a },
458 compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c },
462 first(builder.cache.all::<compile::Assemble>()),
464 compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } },
465 compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } },
466 compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } },
470 first(builder.cache.all::<compile::Rustc>()),
472 compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },
473 compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a },
479 fn test_with_no_doc_stage0() {
480 let mut config = configure(&["A"], &["A"]);
482 config.cmd = Subcommand::Test {
483 paths: vec!["library/std".into()],
487 doc_tests: DocTests::No,
491 rustfix_coverage: false,
496 let build = Build::new(config);
497 let mut builder = Builder::new(&build);
499 let host = TargetSelection::from_user("A");
501 builder.run_step_descriptions(
502 &[StepDescription::from::<test::Crate>()],
503 &["library/std".into()],
506 // Ensure we don't build any compiler artifacts.
507 assert!(!builder.cache.contains::<compile::Rustc>());
509 first(builder.cache.all::<test::Crate>()),
511 compiler: Compiler { host, stage: 0 },
514 test_kind: test::TestKind::Test,
515 krate: INTERNER.intern_str("std"),
522 let mut config = configure(&["A"], &["A"]);
523 config.exclude = vec!["src/tools/tidy".into()];
524 config.cmd = Subcommand::Test {
526 test_args: Vec::new(),
527 rustc_args: Vec::new(),
529 doc_tests: DocTests::No,
533 rustfix_coverage: false,
538 let build = Build::new(config);
539 let builder = Builder::new(&build);
540 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]);
542 // Ensure we have really excluded tidy
543 assert!(!builder.cache.contains::<test::Tidy>());
545 // Ensure other tests are not affected.
546 assert!(builder.cache.contains::<test::RustdocUi>());
551 let mut config = configure(&["A"], &["A"]);
552 config.compiler_docs = true;
553 config.cmd = Subcommand::Doc { paths: Vec::new(), open: false };
554 let build = Build::new(config);
555 let mut builder = Builder::new(&build);
556 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), &[]);
557 let a = TargetSelection::from_user("A");
559 // error_index_generator uses stage 1 to share rustdoc artifacts with the
562 first(builder.cache.all::<doc::ErrorIndex>()),
563 &[doc::ErrorIndex { target: a },]
566 first(builder.cache.all::<tool::ErrorIndex>()),
567 &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }]
569 // This is actually stage 1, but Rustdoc::run swaps out the compiler with
570 // stage minus 1 if --stage is not 0. Very confusing!
572 first(builder.cache.all::<tool::Rustdoc>()),
573 &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },]
579 // Behavior of `x.py test` doing various documentation tests.
580 let mut config = configure(&["A"], &["A"]);
581 config.cmd = Subcommand::Test {
586 doc_tests: DocTests::Yes,
590 rustfix_coverage: false,
594 // Make sure rustfmt binary not being found isn't an error.
595 config.channel = "beta".to_string();
596 let build = Build::new(config);
597 let mut builder = Builder::new(&build);
599 builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]);
600 let a = TargetSelection::from_user("A");
602 // error_index_generator uses stage 1 to share rustdoc artifacts with the
605 first(builder.cache.all::<doc::ErrorIndex>()),
606 &[doc::ErrorIndex { target: a },]
609 first(builder.cache.all::<tool::ErrorIndex>()),
610 &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }]
612 // Unfortunately rustdoc is built twice. Once from stage1 for compiletest
613 // (and other things), and once from stage0 for std crates. Ideally it
614 // would only be built once. If someone wants to fix this, it might be
615 // worth investigating if it would be possible to test std from stage1.
616 // Note that the stages here are +1 than what they actually are because
617 // Rustdoc::run swaps out the compiler with stage minus 1 if --stage is
620 // The stage 0 copy is the one downloaded for bootstrapping. It is
621 // (currently) needed to run "cargo test" on the linkchecker, and
622 // should be relatively "free".
624 first(builder.cache.all::<tool::Rustdoc>()),
626 tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } },
627 tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } },
628 tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },