From d34a1b0c1b4b22cc61b5956c07d89517bf278af8 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 2 Jul 2020 08:07:56 -0400 Subject: Don't duplicate builder code - Add Builder::new_internal --- src/bootstrap/builder.rs | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) (limited to 'src/bootstrap') diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index c1e56347ab1..c1c3c2f3ea7 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -501,16 +501,7 @@ impl<'a> Builder<'a> { _ => return None, }; - let builder = Builder { - build, - top_stage: build.config.stage.unwrap_or(2), - kind, - cache: Cache::new(), - stack: RefCell::new(Vec::new()), - time_spent_on_dependencies: Cell::new(Duration::new(0, 0)), - paths: vec![], - }; - + let builder = Self::new_internal(build, kind, vec![]); let builder = &builder; let mut should_run = ShouldRun::new(builder); for desc in Builder::get_step_descriptions(builder.kind) { @@ -535,6 +526,18 @@ impl<'a> Builder<'a> { Some(help) } + fn new_internal(build: &Build, kind: Kind, paths: Vec) -> Builder<'_> { + Builder { + build, + top_stage: build.config.stage.unwrap_or(2), + kind, + cache: Cache::new(), + stack: RefCell::new(Vec::new()), + time_spent_on_dependencies: Cell::new(Duration::new(0, 0)), + paths, + } + } + pub fn new(build: &Build) -> Builder<'_> { let (kind, paths) = match build.config.cmd { Subcommand::Build { ref paths } => (Kind::Build, &paths[..]), @@ -550,15 +553,7 @@ impl<'a> Builder<'a> { Subcommand::Format { .. } | Subcommand::Clean { .. } => panic!(), }; - Builder { - build, - top_stage: build.config.stage.unwrap_or(2), - kind, - cache: Cache::new(), - stack: RefCell::new(Vec::new()), - time_spent_on_dependencies: Cell::new(Duration::new(0, 0)), - paths: paths.to_owned(), - } + Self::new_internal(build, kind, paths.to_owned()) } pub fn execute_cli(&self) { -- cgit 1.4.1-3-g733a5 From 0192fa4786db80d2c9888af98e7ceec47d327887 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 2 Jul 2020 08:08:09 -0400 Subject: Make the default stage dependent on the subcommand ### x.py build/test: stage 1 I've seen very few people who actually use full stage 2 builds on purpose. These compile rustc and libstd twice and don't give you much more information than a stage 1 build (except in rare cases like https://github.com/rust-lang/rust/pull/68692#discussion_r376392145). For new contributors, this makes the build process even more daunting than it already is. As long as CI is changed to use `--stage 2` I see no downside here. ### x.py bench/dist/install: stage 2 These commands have to do with a finished, optimized version of rustc. It seems very rare to want to use these with a stage 1 build. ### x.py doc: stage 0 Normally when you document things you're just fixing a typo. In this case there is no need to build the whole rust compiler, since the documentation will usually be the same when generated with the beta compiler or with stage 1. Note that for this release cycle only there will be a significant different between stage0 and stage1 docs: https://github.com/rust-lang/rust/pull/73101. However most of the time this will not be the case. --- src/bootstrap/builder.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'src/bootstrap') diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index c1c3c2f3ea7..5c25cfea9f2 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -527,9 +527,22 @@ impl<'a> Builder<'a> { } fn new_internal(build: &Build, kind: Kind, paths: Vec) -> Builder<'_> { + let top_stage = if let Some(explicit_stage) = build.config.stage { + explicit_stage + } else { + // See https://github.com/rust-lang/compiler-team/issues/326 + match kind { + Kind::Doc => 0, + Kind::Build | Kind::Test => 1, + Kind::Bench | Kind::Dist | Kind::Install => 2, + // These are all bootstrap tools, which don't depend on the compiler. + // The stage we pass shouldn't matter, but use 0 just in case. + Kind::Check | Kind::Clippy | Kind::Fix | Kind::Run | Kind::Format => 0, + } + }; Builder { build, - top_stage: build.config.stage.unwrap_or(2), + top_stage, kind, cache: Cache::new(), stack: RefCell::new(Vec::new()), -- cgit 1.4.1-3-g733a5 From f7dcfcd45bd019acf8c914c204ccae519c420adc Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 2 Jul 2020 08:40:34 -0400 Subject: Don't build rustc without std - Set rustc to build only when explicitly asked for This allows building the stage2 rustc artifacts, which nothing depends on. Previously the behavior was as follows (where stageN <-> stage(N-1) artifacts, except for stage0 libstd): - `x.py build --stage 0`: - stage0 libstd - stage1 rustc (but without putting rustc in stage0/) This leaves you without any rustc at all except for the beta compiler (https://github.com/rust-lang/rust/issues/73519). This is never what you want. - `x.py build --stage 1`: - stage0 libstd - stage1 rustc - stage1 libstd - stage1 rustdoc - stage2 rustc This leaves you with a broken stage2 rustc which doesn't even have libcore and is effectively useless. Additionally, it compiles rustc twice, which is not normally what you want. - `x.py build --stage 2`: - stage0 libstd - stage1 rustc - stage1 libstd - stage2 rustc - stage2 rustdoc and tools This builds all tools in release mode. This is the correct usage for CI, but takes far to long for development. Now the behavior is as follows: - `x.py build --stage 0`: - stage0 libstd This is suitable for contributors only working on the standard library, as it means rustc never has to be compiled. - `x.py build --stage 1`: - stage0 libstd - stage1 rustc - stage1 libstd - stage1 rustdoc This is suitable for contributors working on the compiler. It ensures that you have a working rustc and libstd without having to pass `src/libstd` in addition. - `x.py build --stage 2`: - stage0 libstd - stage1 rustc - stage1 libstd - stage2 rustc - stage2 libstd - stage2 rustdoc This is suitable for debugging errors which only appear with the stage2 compiler. - `x.py build --stage 2 src/libstd src/rustc` - stage0 libstd - stage1 rustc - stage1 libstd - stage2 rustc - stage2 libstd - stage2 rustdoc, tools, etc. - stage2 rustc artifacts ('stage3') This is suitable for CI, which wants all tools in release mode. However, most of the use cases for this should use `x.py dist` instead, which builds all the tools without each having to be named individually. --- src/bootstrap/compile.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/bootstrap') diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index e3d1e005373..373e240cb8e 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -446,10 +446,10 @@ pub struct Rustc { impl Step for Rustc { type Output = (); const ONLY_HOSTS: bool = true; - const DEFAULT: bool = true; + const DEFAULT: bool = false; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.all_krates("rustc-main") + run.path("src/rustc") } fn make_run(run: RunConfig<'_>) { -- cgit 1.4.1-3-g733a5 From 01c6256178fb126d668045f3a1297e0f3491e985 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Thu, 2 Jul 2020 08:59:50 -0400 Subject: Change debuginfo to default to 1 if `debug = true` is set From [a conversation in discord](https://discordapp.com/channels/442252698964721669/443151243398086667/719200989269327882): > Linking seems to consume all available RAM, leading to the OS to swap memory to disk and slowing down everything in the process Compiling itself doesn't seem to take up as much RAM, and I'm only looking to check whether a minimal testcase can be compiled by rustc, where the runtime performance isn't much of an issue > do you have debug = true or debuginfo-level = 2 in config.toml? > if so I think that results in over 2GB of debuginfo nowadays and is likely the culprit > which might mean we're giving out bad advice :( Anecdotally, this sped up my stage 1 build from 15 to 10 minutes. This still adds line numbers, it only removes variable and type information. - Improve wording for debuginfo description Co-authored-by: Teymour Aldridge <42674621+teymour-aldridge@users.noreply.github.com> --- config.toml.example | 5 ++++- src/bootstrap/config.rs | 2 +- 2 files changed, 5 insertions(+), 2 deletions(-) (limited to 'src/bootstrap') diff --git a/config.toml.example b/config.toml.example index 01952b21ba4..5d198abe1c7 100644 --- a/config.toml.example +++ b/config.toml.example @@ -341,7 +341,10 @@ # Debuginfo for tests run with compiletest is not controlled by this option # and needs to be enabled separately with `debuginfo-level-tests`. # -# Defaults to 2 if debug is true +# Note that debuginfo-level = 2 generates several gigabytes of debuginfo +# and will slow down the linking process significantly. +# +# Defaults to 1 if debug is true #debuginfo-level = 0 # Debuginfo level for the compiler. diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index d71f3170420..d64ca95d243 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -734,7 +734,7 @@ impl Config { let with_defaults = |debuginfo_level_specific: Option| { debuginfo_level_specific.or(debuginfo_level).unwrap_or(if debug == Some(true) { - 2 + 1 } else { 0 }) -- cgit 1.4.1-3-g733a5 From 74b373426a79af2b21b8d266a881753e338cfd2e Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 13 Jul 2020 19:55:33 -0400 Subject: Fix most bootstrap tests Uses --stage 2 for all the existing tests --- src/bootstrap/builder.rs | 2 +- src/bootstrap/builder/tests.rs | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'src/bootstrap') diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 5c25cfea9f2..f2f0906ff4e 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -232,7 +232,7 @@ impl StepDescription { } if !attempted_run { - panic!("Error: no rules matched {}.", path.display()); + panic!("error: no rules matched {}", path.display()); } } } diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index 6684ca82c27..240553d8baf 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -6,6 +6,7 @@ use pretty_assertions::assert_eq; fn configure(host: &[&str], target: &[&str]) -> Config { let mut config = Config::default_opts(); + config.stage = Some(2); // don't save toolstates config.save_toolstates = None; config.skip_only_host_steps = false; @@ -421,7 +422,7 @@ fn test_exclude() { } #[test] -fn doc_default() { +fn doc_ci() { let mut config = configure(&[], &[]); config.compiler_docs = true; config.cmd = Subcommand::Doc { paths: Vec::new(), open: false }; -- cgit 1.4.1-3-g733a5 From 60c17297383102964ae08bed7e0d2f202959f7f9 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 13 Jul 2020 20:20:42 -0400 Subject: Move tests into a submodule --- src/bootstrap/builder/tests.rs | 931 +++++++++++++++++++++-------------------- 1 file changed, 470 insertions(+), 461 deletions(-) (limited to 'src/bootstrap') diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index 240553d8baf..8e98441afa6 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -2,8 +2,6 @@ use super::*; use crate::config::{Config, TargetSelection}; use std::thread; -use pretty_assertions::assert_eq; - fn configure(host: &[&str], target: &[&str]) -> Config { let mut config = Config::default_opts(); config.stage = Some(2); @@ -36,463 +34,474 @@ fn first(v: Vec<(A, B)>) -> Vec { v.into_iter().map(|(a, _)| a).collect::>() } -#[test] -fn dist_baseline() { - let build = Build::new(configure(&[], &[])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); - - let a = TargetSelection::from_user("A"); - - assert_eq!(first(builder.cache.all::()), &[dist::Docs { host: a },]); - assert_eq!(first(builder.cache.all::()), &[dist::Mingw { host: a },]); - assert_eq!( - first(builder.cache.all::()), - &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },] - ); - assert_eq!( - first(builder.cache.all::()), - &[dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },] - ); - assert_eq!(first(builder.cache.all::()), &[dist::Src]); - // Make sure rustdoc is only built once. - assert_eq!( - first(builder.cache.all::()), - &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },] - ); -} - -#[test] -fn dist_with_targets() { - let build = Build::new(configure(&[], &["B"])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); - - let a = TargetSelection::from_user("A"); - let b = TargetSelection::from_user("B"); - - assert_eq!( - first(builder.cache.all::()), - &[dist::Docs { host: a }, dist::Docs { host: b },] - ); - assert_eq!( - first(builder.cache.all::()), - &[dist::Mingw { host: a }, dist::Mingw { host: b },] - ); - assert_eq!( - first(builder.cache.all::()), - &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },] - ); - assert_eq!( - first(builder.cache.all::()), - &[ - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - dist::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, - ] - ); - assert_eq!(first(builder.cache.all::()), &[dist::Src]); -} - -#[test] -fn dist_with_hosts() { - let build = Build::new(configure(&["B"], &[])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); - - let a = TargetSelection::from_user("A"); - let b = TargetSelection::from_user("B"); - - assert_eq!( - first(builder.cache.all::()), - &[dist::Docs { host: a }, dist::Docs { host: b },] - ); - assert_eq!( - first(builder.cache.all::()), - &[dist::Mingw { host: a }, dist::Mingw { host: b },] - ); - assert_eq!( - first(builder.cache.all::()), - &[ - dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, - dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, - ] - ); - assert_eq!( - first(builder.cache.all::()), - &[ - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, - ] - ); - assert_eq!(first(builder.cache.all::()), &[dist::Src]); -} - -#[test] -fn dist_only_cross_host() { - let a = TargetSelection::from_user("A"); - let b = TargetSelection::from_user("B"); - let mut build = Build::new(configure(&["B"], &[])); - build.config.docs = false; - build.config.extended = true; - build.hosts = vec![b]; - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); - - assert_eq!( - first(builder.cache.all::()), - &[dist::Rustc { compiler: Compiler { host: b, stage: 2 } },] - ); - assert_eq!( - first(builder.cache.all::()), - &[ - compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a }, - compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b }, - ] - ); -} - -#[test] -fn dist_with_targets_and_hosts() { - let build = Build::new(configure(&["B"], &["C"])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); - - let a = TargetSelection::from_user("A"); - let b = TargetSelection::from_user("B"); - let c = TargetSelection::from_user("C"); - - assert_eq!( - first(builder.cache.all::()), - &[dist::Docs { host: a }, dist::Docs { host: b }, dist::Docs { host: c },] - ); - assert_eq!( - first(builder.cache.all::()), - &[dist::Mingw { host: a }, dist::Mingw { host: b }, dist::Mingw { host: c },] - ); - assert_eq!( - first(builder.cache.all::()), - &[ - dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, - dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, - ] - ); - assert_eq!( - first(builder.cache.all::()), - &[ - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, - dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, - ] - ); - assert_eq!(first(builder.cache.all::()), &[dist::Src]); -} - -#[test] -fn dist_with_target_flag() { - let mut config = configure(&["B"], &["C"]); - config.skip_only_host_steps = true; // as-if --target=C was passed - let build = Build::new(config); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); - - let a = TargetSelection::from_user("A"); - let b = TargetSelection::from_user("B"); - let c = TargetSelection::from_user("C"); - - assert_eq!( - first(builder.cache.all::()), - &[dist::Docs { host: a }, dist::Docs { host: b }, dist::Docs { host: c },] - ); - assert_eq!( - first(builder.cache.all::()), - &[dist::Mingw { host: a }, dist::Mingw { host: b }, dist::Mingw { host: c },] - ); - assert_eq!(first(builder.cache.all::()), &[]); - assert_eq!( - first(builder.cache.all::()), - &[ - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, - dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, - ] - ); - assert_eq!(first(builder.cache.all::()), &[]); -} - -#[test] -fn dist_with_same_targets_and_hosts() { - let build = Build::new(configure(&["B"], &["B"])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); - - let a = TargetSelection::from_user("A"); - let b = TargetSelection::from_user("B"); - - assert_eq!( - first(builder.cache.all::()), - &[dist::Docs { host: a }, dist::Docs { host: b },] - ); - assert_eq!( - first(builder.cache.all::()), - &[dist::Mingw { host: a }, dist::Mingw { host: b },] - ); - assert_eq!( - first(builder.cache.all::()), - &[ - dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, - dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, - ] - ); - assert_eq!( - first(builder.cache.all::()), - &[ - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, - ] - ); - assert_eq!(first(builder.cache.all::()), &[dist::Src]); - assert_eq!( - first(builder.cache.all::()), - &[ - compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, - compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, - ] - ); - assert_eq!( - first(builder.cache.all::()), - &[ - compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } }, - compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } }, - ] - ); -} - -#[test] -fn build_default() { - let build = Build::new(configure(&["B"], &["C"])); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); - - let a = TargetSelection::from_user("A"); - let b = TargetSelection::from_user("B"); - let c = TargetSelection::from_user("C"); - - assert_eq!( - first(builder.cache.all::()), - &[ - compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a }, - compile::Std { compiler: Compiler { host: b, stage: 2 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, - compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, - compile::Std { compiler: Compiler { host: b, stage: 2 }, target: b }, - compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, - compile::Std { compiler: Compiler { host: b, stage: 2 }, target: c }, - ] - ); - assert!(!builder.cache.all::().is_empty()); - assert_eq!( - first(builder.cache.all::()), - &[ - compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a }, - compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a }, - compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: a }, - compile::Rustc { compiler: Compiler { host: b, stage: 2 }, target: a }, - compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b }, - compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: b }, - compile::Rustc { compiler: Compiler { host: b, stage: 2 }, target: b }, - ] - ); -} - -#[test] -fn build_with_target_flag() { - let mut config = configure(&["B"], &["C"]); - config.skip_only_host_steps = true; - let build = Build::new(config); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); - - let a = TargetSelection::from_user("A"); - let b = TargetSelection::from_user("B"); - let c = TargetSelection::from_user("C"); - - assert_eq!( - first(builder.cache.all::()), - &[ - compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a }, - compile::Std { compiler: Compiler { host: b, stage: 2 }, target: a }, - compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, - compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, - compile::Std { compiler: Compiler { host: b, stage: 2 }, target: b }, - compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, - compile::Std { compiler: Compiler { host: b, stage: 2 }, target: c }, - ] - ); - assert_eq!( - first(builder.cache.all::()), - &[ - compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, - compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } }, - compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } }, - ] - ); - assert_eq!( - first(builder.cache.all::()), - &[ - compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a }, - compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a }, - compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b }, - ] - ); -} - -#[test] -fn test_with_no_doc_stage0() { - let mut config = configure(&[], &[]); - config.stage = Some(0); - config.cmd = Subcommand::Test { - paths: vec!["library/std".into()], - test_args: vec![], - rustc_args: vec![], - fail_fast: true, - doc_tests: DocTests::No, - bless: false, - compare_mode: None, - rustfix_coverage: false, - pass: None, - }; - - let build = Build::new(config); - let mut builder = Builder::new(&build); - - let host = TargetSelection::from_user("A"); - - builder - .run_step_descriptions(&[StepDescription::from::()], &["library/std".into()]); - - // Ensure we don't build any compiler artifacts. - assert!(!builder.cache.contains::()); - assert_eq!( - first(builder.cache.all::()), - &[test::Crate { - compiler: Compiler { host, stage: 0 }, - target: host, - mode: Mode::Std, - test_kind: test::TestKind::Test, - krate: INTERNER.intern_str("std"), - },] - ); -} - -#[test] -fn test_exclude() { - let mut config = configure(&[], &[]); - config.exclude = vec!["src/tools/tidy".into()]; - config.cmd = Subcommand::Test { - paths: Vec::new(), - test_args: Vec::new(), - rustc_args: Vec::new(), - fail_fast: true, - doc_tests: DocTests::No, - bless: false, - compare_mode: None, - rustfix_coverage: false, - pass: None, - }; - - let build = Build::new(config); - let builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]); - - // Ensure we have really excluded tidy - assert!(!builder.cache.contains::()); - - // Ensure other tests are not affected. - assert!(builder.cache.contains::()); -} - -#[test] -fn doc_ci() { - let mut config = configure(&[], &[]); - config.compiler_docs = true; - config.cmd = Subcommand::Doc { paths: Vec::new(), open: false }; - let build = Build::new(config); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), &[]); - let a = TargetSelection::from_user("A"); - - // error_index_generator uses stage 1 to share rustdoc artifacts with the - // rustdoc tool. - assert_eq!( - first(builder.cache.all::()), - &[doc::ErrorIndex { compiler: Compiler { host: a, stage: 1 }, target: a },] - ); - assert_eq!( - first(builder.cache.all::()), - &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }] - ); - // This is actually stage 1, but Rustdoc::run swaps out the compiler with - // stage minus 1 if --stage is not 0. Very confusing! - assert_eq!( - first(builder.cache.all::()), - &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },] - ); -} - -//FIXME(mark-i-m): reinstate this test when things are fixed... -//#[test] -#[allow(dead_code)] -fn test_docs() { - // Behavior of `x.py test` doing various documentation tests. - let mut config = configure(&[], &[]); - config.cmd = Subcommand::Test { - paths: vec![], - test_args: vec![], - rustc_args: vec![], - fail_fast: true, - doc_tests: DocTests::Yes, - bless: false, - compare_mode: None, - rustfix_coverage: false, - pass: None, - }; - let build = Build::new(config); - let mut builder = Builder::new(&build); - builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]); - let a = TargetSelection::from_user("A"); - - // error_index_generator uses stage 1 to share rustdoc artifacts with the - // rustdoc tool. - assert_eq!( - first(builder.cache.all::()), - &[doc::ErrorIndex { compiler: Compiler { host: a, stage: 1 }, target: a },] - ); - assert_eq!( - first(builder.cache.all::()), - &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }] - ); - // Unfortunately rustdoc is built twice. Once from stage1 for compiletest - // (and other things), and once from stage0 for std crates. Ideally it - // would only be built once. If someone wants to fix this, it might be - // worth investigating if it would be possible to test std from stage1. - // Note that the stages here are +1 than what they actually are because - // Rustdoc::run swaps out the compiler with stage minus 1 if --stage is - // not 0. - assert_eq!( - first(builder.cache.all::()), - &[ - tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }, - tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } }, - ] - ); +mod dist { + use super::{configure, first}; + use crate::builder::*; + use pretty_assertions::assert_eq; + + #[test] + fn dist_baseline() { + let build = Build::new(configure(&[], &[])); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + + let a = TargetSelection::from_user("A"); + + assert_eq!(first(builder.cache.all::()), &[dist::Docs { host: a },]); + assert_eq!(first(builder.cache.all::()), &[dist::Mingw { host: a },]); + assert_eq!( + first(builder.cache.all::()), + &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },] + ); + assert_eq!( + first(builder.cache.all::()), + &[dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a },] + ); + assert_eq!(first(builder.cache.all::()), &[dist::Src]); + // Make sure rustdoc is only built once. + assert_eq!( + first(builder.cache.all::()), + &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },] + ); + } + + #[test] + fn dist_with_targets() { + let build = Build::new(configure(&[], &["B"])); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + + let a = TargetSelection::from_user("A"); + let b = TargetSelection::from_user("B"); + + assert_eq!( + first(builder.cache.all::()), + &[dist::Docs { host: a }, dist::Docs { host: b },] + ); + assert_eq!( + first(builder.cache.all::()), + &[dist::Mingw { host: a }, dist::Mingw { host: b },] + ); + assert_eq!( + first(builder.cache.all::()), + &[dist::Rustc { compiler: Compiler { host: a, stage: 2 } },] + ); + assert_eq!( + first(builder.cache.all::()), + &[ + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + dist::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, + ] + ); + assert_eq!(first(builder.cache.all::()), &[dist::Src]); + } + + #[test] + fn dist_with_hosts() { + let build = Build::new(configure(&["B"], &[])); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + + let a = TargetSelection::from_user("A"); + let b = TargetSelection::from_user("B"); + + assert_eq!( + first(builder.cache.all::()), + &[dist::Docs { host: a }, dist::Docs { host: b },] + ); + assert_eq!( + first(builder.cache.all::()), + &[dist::Mingw { host: a }, dist::Mingw { host: b },] + ); + assert_eq!( + first(builder.cache.all::()), + &[ + dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, + dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, + ] + ); + assert_eq!( + first(builder.cache.all::()), + &[ + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + ] + ); + assert_eq!(first(builder.cache.all::()), &[dist::Src]); + } + + #[test] + fn dist_only_cross_host() { + let a = TargetSelection::from_user("A"); + let b = TargetSelection::from_user("B"); + let mut build = Build::new(configure(&["B"], &[])); + build.config.docs = false; + build.config.extended = true; + build.hosts = vec![b]; + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + + assert_eq!( + first(builder.cache.all::()), + &[dist::Rustc { compiler: Compiler { host: b, stage: 2 } },] + ); + assert_eq!( + first(builder.cache.all::()), + &[ + compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b }, + ] + ); + } + + #[test] + fn dist_with_targets_and_hosts() { + let build = Build::new(configure(&["B"], &["C"])); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + + let a = TargetSelection::from_user("A"); + let b = TargetSelection::from_user("B"); + let c = TargetSelection::from_user("C"); + + assert_eq!( + first(builder.cache.all::()), + &[dist::Docs { host: a }, dist::Docs { host: b }, dist::Docs { host: c },] + ); + assert_eq!( + first(builder.cache.all::()), + &[dist::Mingw { host: a }, dist::Mingw { host: b }, dist::Mingw { host: c },] + ); + assert_eq!( + first(builder.cache.all::()), + &[ + dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, + dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, + ] + ); + assert_eq!( + first(builder.cache.all::()), + &[ + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, + ] + ); + assert_eq!(first(builder.cache.all::()), &[dist::Src]); + } + + #[test] + fn dist_with_target_flag() { + let mut config = configure(&["B"], &["C"]); + config.skip_only_host_steps = true; // as-if --target=C was passed + let build = Build::new(config); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + + let a = TargetSelection::from_user("A"); + let b = TargetSelection::from_user("B"); + let c = TargetSelection::from_user("C"); + + assert_eq!( + first(builder.cache.all::()), + &[dist::Docs { host: a }, dist::Docs { host: b }, dist::Docs { host: c },] + ); + assert_eq!( + first(builder.cache.all::()), + &[dist::Mingw { host: a }, dist::Mingw { host: b }, dist::Mingw { host: c },] + ); + assert_eq!(first(builder.cache.all::()), &[]); + assert_eq!( + first(builder.cache.all::()), + &[ + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + dist::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, + ] + ); + assert_eq!(first(builder.cache.all::()), &[]); + } + + #[test] + fn dist_with_same_targets_and_hosts() { + let build = Build::new(configure(&["B"], &["B"])); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Dist), &[]); + + let a = TargetSelection::from_user("A"); + let b = TargetSelection::from_user("B"); + + assert_eq!( + first(builder.cache.all::()), + &[dist::Docs { host: a }, dist::Docs { host: b },] + ); + assert_eq!( + first(builder.cache.all::()), + &[dist::Mingw { host: a }, dist::Mingw { host: b },] + ); + assert_eq!( + first(builder.cache.all::()), + &[ + dist::Rustc { compiler: Compiler { host: a, stage: 2 } }, + dist::Rustc { compiler: Compiler { host: b, stage: 2 } }, + ] + ); + assert_eq!( + first(builder.cache.all::()), + &[ + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + dist::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + ] + ); + assert_eq!(first(builder.cache.all::()), &[dist::Src]); + assert_eq!( + first(builder.cache.all::()), + &[ + compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, + ] + ); + assert_eq!( + first(builder.cache.all::()), + &[ + compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, + compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, + compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } }, + compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } }, + ] + ); + } + + #[test] + fn build_default() { + let build = Build::new(configure(&["B"], &["C"])); + let mut builder = Builder::new(&build); + builder.run_step_descriptions( + &Builder::get_step_descriptions(Kind::Build), + &["src/rustc".into(), "src/libstd".into()], + ); + + let a = TargetSelection::from_user("A"); + let b = TargetSelection::from_user("B"); + let c = TargetSelection::from_user("C"); + + assert_eq!( + first(builder.cache.all::()), + &[ + compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: b }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: c }, + ] + ); + assert!(!builder.cache.all::().is_empty()); + assert_eq!( + first(builder.cache.all::()), + &[ + compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: a }, + compile::Rustc { compiler: Compiler { host: b, stage: 2 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b }, + compile::Rustc { compiler: Compiler { host: a, stage: 2 }, target: b }, + compile::Rustc { compiler: Compiler { host: b, stage: 2 }, target: b }, + ] + ); + } + + #[test] + fn build_with_target_flag() { + let mut config = configure(&["B"], &["C"]); + config.skip_only_host_steps = true; + let build = Build::new(config); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); + + let a = TargetSelection::from_user("A"); + let b = TargetSelection::from_user("B"); + let c = TargetSelection::from_user("C"); + + assert_eq!( + first(builder.cache.all::()), + &[ + compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: a }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: b }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: b }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: b }, + compile::Std { compiler: Compiler { host: a, stage: 2 }, target: c }, + compile::Std { compiler: Compiler { host: b, stage: 2 }, target: c }, + ] + ); + assert_eq!( + first(builder.cache.all::()), + &[ + compile::Assemble { target_compiler: Compiler { host: a, stage: 0 } }, + compile::Assemble { target_compiler: Compiler { host: a, stage: 1 } }, + compile::Assemble { target_compiler: Compiler { host: a, stage: 2 } }, + compile::Assemble { target_compiler: Compiler { host: b, stage: 2 } }, + ] + ); + assert_eq!( + first(builder.cache.all::()), + &[ + compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: a }, + compile::Rustc { compiler: Compiler { host: a, stage: 1 }, target: b }, + ] + ); + } + + #[test] + fn test_with_no_doc_stage0() { + let mut config = configure(&[], &[]); + config.stage = Some(0); + config.cmd = Subcommand::Test { + paths: vec!["library/std".into()], + test_args: vec![], + rustc_args: vec![], + fail_fast: true, + doc_tests: DocTests::No, + bless: false, + compare_mode: None, + rustfix_coverage: false, + pass: None, + }; + + let build = Build::new(config); + let mut builder = Builder::new(&build); + + let host = TargetSelection::from_user("A"); + + builder.run_step_descriptions( + &[StepDescription::from::()], + &["library/std".into()], + ); + + // Ensure we don't build any compiler artifacts. + assert!(!builder.cache.contains::()); + assert_eq!( + first(builder.cache.all::()), + &[test::Crate { + compiler: Compiler { host, stage: 0 }, + target: host, + mode: Mode::Std, + test_kind: test::TestKind::Test, + krate: INTERNER.intern_str("std"), + },] + ); + } + + #[test] + fn test_exclude() { + let mut config = configure(&[], &[]); + config.exclude = vec!["src/tools/tidy".into()]; + config.cmd = Subcommand::Test { + paths: Vec::new(), + test_args: Vec::new(), + rustc_args: Vec::new(), + fail_fast: true, + doc_tests: DocTests::No, + bless: false, + compare_mode: None, + rustfix_coverage: false, + pass: None, + }; + + let build = Build::new(config); + let builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]); + + // Ensure we have really excluded tidy + assert!(!builder.cache.contains::()); + + // Ensure other tests are not affected. + assert!(builder.cache.contains::()); + } + + #[test] + fn doc_ci() { + let mut config = configure(&[], &[]); + config.compiler_docs = true; + config.cmd = Subcommand::Doc { paths: Vec::new(), open: false }; + let build = Build::new(config); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), &[]); + let a = TargetSelection::from_user("A"); + + // error_index_generator uses stage 1 to share rustdoc artifacts with the + // rustdoc tool. + assert_eq!( + first(builder.cache.all::()), + &[doc::ErrorIndex { compiler: Compiler { host: a, stage: 1 }, target: a },] + ); + assert_eq!( + first(builder.cache.all::()), + &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }] + ); + // This is actually stage 1, but Rustdoc::run swaps out the compiler with + // stage minus 1 if --stage is not 0. Very confusing! + assert_eq!( + first(builder.cache.all::()), + &[tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } },] + ); + } + + //FIXME(mark-i-m): reinstate this test when things are fixed... + //#[test] + #[allow(dead_code)] + fn test_docs() { + // Behavior of `x.py test` doing various documentation tests. + let mut config = configure(&[], &[]); + config.cmd = Subcommand::Test { + paths: vec![], + test_args: vec![], + rustc_args: vec![], + fail_fast: true, + doc_tests: DocTests::Yes, + bless: false, + compare_mode: None, + rustfix_coverage: false, + pass: None, + }; + let build = Build::new(config); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Test), &[]); + let a = TargetSelection::from_user("A"); + + // error_index_generator uses stage 1 to share rustdoc artifacts with the + // rustdoc tool. + assert_eq!( + first(builder.cache.all::()), + &[doc::ErrorIndex { compiler: Compiler { host: a, stage: 1 }, target: a },] + ); + assert_eq!( + first(builder.cache.all::()), + &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 1 } }] + ); + // Unfortunately rustdoc is built twice. Once from stage1 for compiletest + // (and other things), and once from stage0 for std crates. Ideally it + // would only be built once. If someone wants to fix this, it might be + // worth investigating if it would be possible to test std from stage1. + // Note that the stages here are +1 than what they actually are because + // Rustdoc::run swaps out the compiler with stage minus 1 if --stage is + // not 0. + assert_eq!( + first(builder.cache.all::()), + &[ + tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }, + tool::Rustdoc { compiler: Compiler { host: a, stage: 2 } }, + ] + ); + } } -- cgit 1.4.1-3-g733a5 From cdca33754771e6b10e9399c8d7780e391963305e Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 13 Jul 2020 20:25:21 -0400 Subject: Add tests for the new behavior - Only set stage 2 in dist tests - Add test for `x.py doc` without args - Add test for `x.py build` without args - Add test for `x.py build --stage 0` --- src/bootstrap/builder/tests.rs | 95 ++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 92 insertions(+), 3 deletions(-) (limited to 'src/bootstrap') diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index 8e98441afa6..d6056565356 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -4,7 +4,6 @@ use std::thread; fn configure(host: &[&str], target: &[&str]) -> Config { let mut config = Config::default_opts(); - config.stage = Some(2); // don't save toolstates config.save_toolstates = None; config.skip_only_host_steps = false; @@ -34,11 +33,101 @@ fn first(v: Vec<(A, B)>) -> Vec { v.into_iter().map(|(a, _)| a).collect::>() } -mod dist { +mod defaults { use super::{configure, first}; use crate::builder::*; + use crate::Config; use pretty_assertions::assert_eq; + #[test] + fn build_default() { + let build = Build::new(configure(&[], &[])); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); + + let a = TargetSelection::from_user("A"); + assert_eq!( + first(builder.cache.all::()), + &[ + compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a }, + compile::Std { compiler: Compiler { host: a, stage: 1 }, target: a }, + ] + ); + assert!(!builder.cache.all::().is_empty()); + // Make sure rustdoc is only built once. + assert_eq!( + first(builder.cache.all::()), + // Recall that rustdoc stages are off-by-one + // - this is the compiler it's _linked_ to, not built with. + &[tool::Rustdoc { compiler: Compiler { host: a, stage: 1 } }], + ); + assert_eq!( + first(builder.cache.all::()), + &[compile::Rustc { compiler: Compiler { host: a, stage: 0 }, target: a },] + ); + } + + #[test] + fn build_stage_0() { + let config = Config { stage: Some(0), ..configure(&[], &[]) }; + let build = Build::new(config); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Build), &[]); + + let a = TargetSelection::from_user("A"); + assert_eq!( + first(builder.cache.all::()), + &[compile::Std { compiler: Compiler { host: a, stage: 0 }, target: a },] + ); + assert!(!builder.cache.all::().is_empty()); + assert_eq!( + first(builder.cache.all::()), + // This is the beta rustdoc. + // Add an assert here to make sure this is the only rustdoc built. + &[tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } }], + ); + assert!(builder.cache.all::().is_empty()); + } + + #[test] + fn doc_default() { + let mut config = configure(&[], &[]); + config.compiler_docs = true; + config.cmd = Subcommand::Doc { paths: Vec::new(), open: false }; + let build = Build::new(config); + let mut builder = Builder::new(&build); + builder.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), &[]); + let a = TargetSelection::from_user("A"); + + // error_index_generator uses stage 0 to share rustdoc artifacts with the + // rustdoc tool. + assert_eq!( + first(builder.cache.all::()), + &[doc::ErrorIndex { compiler: Compiler { host: a, stage: 0 }, target: a },] + ); + assert_eq!( + first(builder.cache.all::()), + &[tool::ErrorIndex { compiler: Compiler { host: a, stage: 0 } }] + ); + // docs should be built with the beta compiler, not with the stage0 artifacts. + // recall that rustdoc is off-by-one: `stage` is the compiler rustdoc is _linked_ to, + // not the one it was built by. + assert_eq!( + first(builder.cache.all::()), + &[tool::Rustdoc { compiler: Compiler { host: a, stage: 0 } },] + ); + } +} + +mod dist { + use super::{first, Config}; + use crate::builder::*; + use pretty_assertions::assert_eq; + + fn configure(host: &[&str], target: &[&str]) -> Config { + Config { stage: Some(2), ..super::configure(host, target) } + } + #[test] fn dist_baseline() { let build = Build::new(configure(&[], &[])); @@ -276,7 +365,7 @@ mod dist { } #[test] - fn build_default() { + fn build_all() { let build = Build::new(configure(&["B"], &["C"])); let mut builder = Builder::new(&build); builder.run_step_descriptions( -- cgit 1.4.1-3-g733a5 From 7768eaa0503e7e98eb2404fa4664297a84d72d38 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 27 Jul 2020 15:53:01 -0400 Subject: Add assert that tests happen with stage 2 in CI - Use stage 2 for makefile - Move assert to builder - Don't add an assert for --help - Allow --stage 0 if passed explicitly - Don't assert defaults during tests Otherwise it's impossible to test the defaults! --- src/bootstrap/builder.rs | 16 +++++++++++++++- src/bootstrap/mk/Makefile.in | 34 +++++++++++++++++----------------- 2 files changed, 32 insertions(+), 18 deletions(-) (limited to 'src/bootstrap') diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index f2f0906ff4e..a7add4cd559 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -540,6 +540,7 @@ impl<'a> Builder<'a> { Kind::Check | Kind::Clippy | Kind::Fix | Kind::Run | Kind::Format => 0, } }; + Builder { build, top_stage, @@ -566,7 +567,20 @@ impl<'a> Builder<'a> { Subcommand::Format { .. } | Subcommand::Clean { .. } => panic!(), }; - Self::new_internal(build, kind, paths.to_owned()) + let this = Self::new_internal(build, kind, paths.to_owned()); + + // CI should always run stage 2 builds, unless it specifically states otherwise + #[cfg(not(test))] + if build.config.stage.is_none() && build.ci_env != crate::CiEnv::None { + match kind { + Kind::Test | Kind::Doc | Kind::Build | Kind::Bench | Kind::Dist | Kind::Install => { + assert_eq!(this.top_stage, 2) + } + _ => {} + } + } + + this } pub fn execute_cli(&self) { diff --git a/src/bootstrap/mk/Makefile.in b/src/bootstrap/mk/Makefile.in index e5b9f27c258..1564cfb0619 100644 --- a/src/bootstrap/mk/Makefile.in +++ b/src/bootstrap/mk/Makefile.in @@ -9,8 +9,8 @@ endif BOOTSTRAP := $(CFG_PYTHON) $(CFG_SRC_DIR)src/bootstrap/bootstrap.py all: - $(Q)$(BOOTSTRAP) build $(BOOTSTRAP_ARGS) - $(Q)$(BOOTSTRAP) doc $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) build --stage 2 $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) doc --stage 2 $(BOOTSTRAP_ARGS) help: $(Q)echo 'Welcome to the rustbuild build system!' @@ -31,17 +31,17 @@ rustc-stage2: docs: doc doc: - $(Q)$(BOOTSTRAP) doc $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) doc --stage 2 $(BOOTSTRAP_ARGS) nomicon: - $(Q)$(BOOTSTRAP) doc src/doc/nomicon $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) doc --stage 2 src/doc/nomicon $(BOOTSTRAP_ARGS) book: - $(Q)$(BOOTSTRAP) doc src/doc/book $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) doc --stage 2 src/doc/book $(BOOTSTRAP_ARGS) standalone-docs: - $(Q)$(BOOTSTRAP) doc src/doc $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) doc --stage 2 src/doc $(BOOTSTRAP_ARGS) check: - $(Q)$(BOOTSTRAP) test $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) test --stage 2 $(BOOTSTRAP_ARGS) check-aux: - $(Q)$(BOOTSTRAP) test \ + $(Q)$(BOOTSTRAP) test --stage 2 \ src/tools/cargo \ src/tools/cargotest \ $(BOOTSTRAP_ARGS) @@ -51,18 +51,18 @@ dist: $(Q)$(BOOTSTRAP) dist $(BOOTSTRAP_ARGS) distcheck: $(Q)$(BOOTSTRAP) dist $(BOOTSTRAP_ARGS) - $(Q)$(BOOTSTRAP) test distcheck $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) test --stage 2 distcheck $(BOOTSTRAP_ARGS) install: $(Q)$(BOOTSTRAP) install $(BOOTSTRAP_ARGS) tidy: - $(Q)$(BOOTSTRAP) test src/tools/tidy $(BOOTSTRAP_ARGS) + $(Q)$(BOOTSTRAP) test --stage 2 src/tools/tidy $(BOOTSTRAP_ARGS) prepare: - $(Q)$(BOOTSTRAP) build nonexistent/path/to/trigger/cargo/metadata + $(Q)$(BOOTSTRAP) build --stage 2 nonexistent/path/to/trigger/cargo/metadata check-stage2-T-arm-linux-androideabi-H-x86_64-unknown-linux-gnu: - $(Q)$(BOOTSTRAP) test --target arm-linux-androideabi + $(Q)$(BOOTSTRAP) test --stage 2 --target arm-linux-androideabi check-stage2-T-x86_64-unknown-linux-musl-H-x86_64-unknown-linux-gnu: - $(Q)$(BOOTSTRAP) test --target x86_64-unknown-linux-musl + $(Q)$(BOOTSTRAP) test --stage 2 --target x86_64-unknown-linux-musl TESTS_IN_2 := \ src/test/ui \ @@ -70,18 +70,18 @@ TESTS_IN_2 := \ src/tools/linkchecker ci-subset-1: - $(Q)$(BOOTSTRAP) test $(TESTS_IN_2:%=--exclude %) + $(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_2:%=--exclude %) ci-subset-2: - $(Q)$(BOOTSTRAP) test $(TESTS_IN_2) + $(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_2) TESTS_IN_MINGW_2 := \ src/test/ui \ src/test/compile-fail ci-mingw-subset-1: - $(Q)$(BOOTSTRAP) test $(TESTS_IN_MINGW_2:%=--exclude %) + $(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_MINGW_2:%=--exclude %) ci-mingw-subset-2: - $(Q)$(BOOTSTRAP) test $(TESTS_IN_MINGW_2) + $(Q)$(BOOTSTRAP) test --stage 2 $(TESTS_IN_MINGW_2) .PHONY: dist -- cgit 1.4.1-3-g733a5 From a5337d668c4976fed89551f94b03b2903f8f947c Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Mon, 27 Jul 2020 21:53:10 -0400 Subject: Use exhaustive match for assert --- src/bootstrap/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/bootstrap') diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index a7add4cd559..144e146685f 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -576,7 +576,7 @@ impl<'a> Builder<'a> { Kind::Test | Kind::Doc | Kind::Build | Kind::Bench | Kind::Dist | Kind::Install => { assert_eq!(this.top_stage, 2) } - _ => {} + Kind::Check | Kind::Clippy | Kind::Fix | Kind::Run | Kind::Format => {} } } -- cgit 1.4.1-3-g733a5 From c4c6453b7ba42c5114e875908eeaf510398d2f38 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 28 Jul 2020 08:34:59 -0400 Subject: Fix bad rebase --- src/bootstrap/builder/tests.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/bootstrap') diff --git a/src/bootstrap/builder/tests.rs b/src/bootstrap/builder/tests.rs index d6056565356..4293844fcbf 100644 --- a/src/bootstrap/builder/tests.rs +++ b/src/bootstrap/builder/tests.rs @@ -370,7 +370,7 @@ mod dist { let mut builder = Builder::new(&build); builder.run_step_descriptions( &Builder::get_step_descriptions(Kind::Build), - &["src/rustc".into(), "src/libstd".into()], + &["src/rustc".into(), "library/std".into()], ); let a = TargetSelection::from_user("A"); -- cgit 1.4.1-3-g733a5 From da40cf81e63d04dced9d943743bb2a58801916e7 Mon Sep 17 00:00:00 2001 From: Joshua Nelson Date: Tue, 28 Jul 2020 09:36:56 -0400 Subject: Use --stage 2 in checktools - Remove useless --stage 2 argument to checktools.sh - Fix help text for expand-yaml-anchors (it had a typo) --- .github/workflows/ci.yml | 2 +- src/bootstrap/flags.rs | 2 +- src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile | 2 +- src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh | 6 +++--- src/ci/github-actions/ci.yml | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) (limited to 'src/bootstrap') diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9b35208bf32..565c916db5b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -414,7 +414,7 @@ jobs: os: windows-latest-xl - name: x86_64-msvc-tools env: - SCRIPT: src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py --stage 2 /tmp/toolstate/toolstates.json windows + SCRIPT: src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstate/toolstates.json windows RUST_CONFIGURE_ARGS: "--build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstate/toolstates.json" os: windows-latest-xl - name: i686-mingw-1 diff --git a/src/bootstrap/flags.rs b/src/bootstrap/flags.rs index a298b299667..56e4f0467cc 100644 --- a/src/bootstrap/flags.rs +++ b/src/bootstrap/flags.rs @@ -425,7 +425,7 @@ Arguments: This subcommand accepts a number of paths to tools to build and run. For example: - ./x.py run src/tool/expand-yaml-anchors + ./x.py run src/tools/expand-yaml-anchors At least a tool needs to be called.", ); diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile index e99b3f6ec37..ef17f0507ab 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/Dockerfile @@ -22,4 +22,4 @@ COPY host-x86_64/x86_64-gnu-tools/checktools.sh /tmp/ ENV RUST_CONFIGURE_ARGS \ --build=x86_64-unknown-linux-gnu \ --save-toolstates=/tmp/toolstate/toolstates.json -ENV SCRIPT /tmp/checktools.sh ../x.py --stage 2 +ENV SCRIPT /tmp/checktools.sh ../x.py diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh index b4b23a245e0..49a8e5e88a0 100755 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh @@ -7,7 +7,7 @@ X_PY="$1" # Try to test all the tools and store the build/test success in the TOOLSTATE_FILE set +e -python3 "$X_PY" test --no-fail-fast \ +python3 "$X_PY" test --stage 2 --no-fail-fast \ src/doc/book \ src/doc/nomicon \ src/doc/reference \ @@ -22,5 +22,5 @@ set -e # debugging: print out the saved toolstates cat /tmp/toolstate/toolstates.json -python3 "$X_PY" test check-tools -python3 "$X_PY" test src/tools/clippy +python3 "$X_PY" test --stage 2 check-tools +python3 "$X_PY" test --stage 2 src/tools/clippy diff --git a/src/ci/github-actions/ci.yml b/src/ci/github-actions/ci.yml index b31f00c0322..a7c1987e8b1 100644 --- a/src/ci/github-actions/ci.yml +++ b/src/ci/github-actions/ci.yml @@ -481,7 +481,7 @@ jobs: - name: x86_64-msvc-tools env: - SCRIPT: src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py --stage 2 /tmp/toolstate/toolstates.json windows + SCRIPT: src/ci/docker/host-x86_64/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstate/toolstates.json windows RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstate/toolstates.json <<: *job-windows-xl -- cgit 1.4.1-3-g733a5