diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index f419bebdc1263..7df5ff179fdf5 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -365,6 +365,7 @@ impl Step for RustAnalyzer { "src/tools/rust-analyzer", SourceType::InTree, &["in-rust-tree".to_owned()], + vec![], ); cargo.allow_features(crate::core::build_steps::tool::RustAnalyzer::ALLOW_FEATURES); @@ -440,6 +441,8 @@ macro_rules! tool_check_step { $path, $source_type, &[], + vec![], + ); // For ./x.py clippy, don't run with --all-targets because diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs index cd198c425c008..912da68132e70 100644 --- a/src/bootstrap/src/core/build_steps/clippy.rs +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -263,6 +263,7 @@ macro_rules! lint_any { $path, SourceType::InTree, &[], + vec![] ); let _guard = builder.msg_tool( diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index ca2b874264788..9ae3927b2a480 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -13,7 +13,7 @@ use std::{env, fs, mem}; use crate::Mode; use crate::core::build_steps::compile; -use crate::core::build_steps::tool::{self, SourceType, Tool, prepare_tool_cargo}; +use crate::core::build_steps::tool::{self, CompileStep, SourceType, Tool, prepare_tool_cargo}; use crate::core::builder::{ self, Alias, Builder, Compiler, Kind, RunConfig, ShouldRun, Step, crate_description, }; @@ -948,7 +948,8 @@ macro_rules! tool_doc { t!(fs::create_dir_all(&out)); let compiler = builder.compiler(stage, builder.config.build); - builder.ensure(compile::Std::new(compiler, target)); + let mut steps = vec![]; + steps.push(CompileStep::Std(target)); if true $(&& $rustc_tool)? { // Build rustc docs so that we generate relative links. @@ -957,7 +958,8 @@ macro_rules! tool_doc { // Rustdoc needs the rustc sysroot available to build. // FIXME: is there a way to only ensure `check::Rustc` here? Last time I tried it failed // with strange errors, but only on a full bors test ... - builder.ensure(compile::Rustc::new(compiler, target)); + steps.push(CompileStep::Rustc(target, None)); + } // Build cargo command. @@ -970,6 +972,7 @@ macro_rules! tool_doc { $path, source_type, &[], + steps ); cargo.arg("-Zskip-rustdoc-fingerprint"); diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index c7bcd76caddb9..2e40a1708fe0a 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -146,6 +146,7 @@ impl Step for Miri { "src/tools/miri", SourceType::InTree, &[], + vec![], ); miri.add_rustc_lib_path(builder); miri.arg("--").arg("--target").arg(target.rustc_target_arg()); diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index e25b571acbac5..531ab6e90227c 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -11,7 +11,7 @@ use clap_complete::shells; use crate::core::build_steps::doc::DocumentationFormat; use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget; -use crate::core::build_steps::tool::{self, SourceType, Tool}; +use crate::core::build_steps::tool::{self, CompileStep, SourceType, Tool}; use crate::core::build_steps::toolstate::ToolState; use crate::core::build_steps::{compile, dist, llvm}; use crate::core::builder::{ @@ -71,6 +71,7 @@ impl Step for CrateBootstrap { path, SourceType::InTree, &[], + vec![], ); let crate_name = path.rsplit_once('/').unwrap().1; run_cargo_test(cargo, &[], &[], crate_name, crate_name, compiler, bootstrap_host, builder); @@ -122,6 +123,7 @@ You can skip linkcheck with --skip src/tools/linkchecker" "src/tools/linkchecker", SourceType::InTree, &[], + vec![], ); run_cargo_test( cargo, @@ -277,7 +279,6 @@ impl Step for Cargo { fn run(self, builder: &Builder<'_>) { let compiler = builder.compiler(self.stage, self.host); - builder.ensure(tool::Cargo { compiler, target: self.host }); let cargo = tool::prepare_tool_cargo( builder, compiler, @@ -287,6 +288,7 @@ impl Step for Cargo { "src/tools/cargo", SourceType::Submodule, &[], + vec![CompileStep::Cargo(self.host)], ); // NOTE: can't use `run_cargo_test` because we need to overwrite `PATH` @@ -341,10 +343,6 @@ impl Step for RustAnalyzer { let host = self.host; let compiler = builder.compiler(stage, host); - // We don't need to build the whole Rust Analyzer for the proc-macro-srv test suite, - // but we do need the standard library to be present. - builder.ensure(compile::Rustc::new(compiler, host)); - let workspace_path = "src/tools/rust-analyzer"; // until the whole RA test suite runs on `i686`, we only run // `proc-macro-srv` tests @@ -358,6 +356,9 @@ impl Step for RustAnalyzer { crate_path, SourceType::InTree, &["in-rust-tree".to_owned()], + // We don't need to build the whole Rust Analyzer for the proc-macro-srv test suite, + // but we do need the standard library to be present. + vec![CompileStep::Rustc(host, None)], ); cargo.allow_features(tool::RustAnalyzer::ALLOW_FEATURES); @@ -399,8 +400,6 @@ impl Step for Rustfmt { let host = self.host; let compiler = builder.compiler(stage, host); - builder.ensure(tool::Rustfmt { compiler, target: self.host, extra_features: Vec::new() }); - let mut cargo = tool::prepare_tool_cargo( builder, compiler, @@ -410,6 +409,7 @@ impl Step for Rustfmt { "src/tools/rustfmt", SourceType::InTree, &[], + vec![CompileStep::RustFmt(self.host)], ); let dir = testdir(builder, compiler.host); @@ -516,7 +516,6 @@ impl Step for Miri { // We also need sysroots, for Miri and for the host (the latter for build scripts). // This is for the tests so everything is done with the target compiler. let miri_sysroot = Miri::build_miri_sysroot(builder, target_compiler, target); - builder.ensure(compile::Std::new(target_compiler, host)); let host_sysroot = builder.sysroot(target_compiler); // Miri has its own "target dir" for ui test dependencies. Make sure it gets cleared when @@ -540,6 +539,7 @@ impl Step for Miri { "src/tools/miri", SourceType::InTree, &[], + vec![CompileStep::Std(host)], ); cargo.add_rustc_lib_path(builder); @@ -630,6 +630,7 @@ impl Step for CargoMiri { "src/tools/miri/test-cargo-miri", SourceType::Submodule, &[], + vec![], ); // We're not using `prepare_cargo_test` so we have to do this ourselves. @@ -676,9 +677,6 @@ impl Step for CompiletestTest { let host = self.host; let compiler = builder.compiler(builder.top_stage, host); - // We need `ToolStd` for the locally-built sysroot because - // compiletest uses unstable features of the `test` crate. - builder.ensure(compile::Std::new(compiler, host)); let mut cargo = tool::prepare_tool_cargo( builder, compiler, @@ -690,6 +688,9 @@ impl Step for CompiletestTest { "src/tools/compiletest", SourceType::InTree, &[], + // We need `ToolStd` for the locally-built sysroot because + // compiletest uses unstable features of the `test` crate. + vec![CompileStep::Std(host)], ); cargo.allow_features("test"); run_cargo_test( @@ -730,7 +731,6 @@ impl Step for Clippy { let host = self.host; let compiler = builder.compiler(stage, host); - builder.ensure(tool::Clippy { compiler, target: self.host, extra_features: Vec::new() }); let mut cargo = tool::prepare_tool_cargo( builder, compiler, @@ -740,6 +740,7 @@ impl Step for Clippy { "src/tools/clippy", SourceType::InTree, &[], + vec![CompileStep::Clippy(self.host)], ); cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler)); @@ -1274,8 +1275,6 @@ impl Step for RunMakeSupport { /// Builds run-make-support and returns the path to the resulting rlib. fn run(self, builder: &Builder<'_>) -> PathBuf { - builder.ensure(compile::Std::new(self.compiler, self.target)); - let cargo = tool::prepare_tool_cargo( builder, self.compiler, @@ -1285,6 +1284,7 @@ impl Step for RunMakeSupport { "src/tools/run-make-support", SourceType::InTree, &[], + vec![CompileStep::Std(self.target)], ); cargo.into_cmd().run(builder); @@ -1329,6 +1329,7 @@ impl Step for CrateRunMakeSupport { "src/tools/run-make-support", SourceType::InTree, &[], + vec![], ); cargo.allow_features("test"); run_cargo_test( @@ -1375,6 +1376,7 @@ impl Step for CrateBuildHelper { "src/tools/build_helper", SourceType::InTree, &[], + vec![], ); cargo.allow_features("test"); run_cargo_test( @@ -2762,8 +2764,9 @@ impl Step for CrateRustdoc { // using `download-rustc`, the rustc_private artifacts may be in a *different sysroot* from // the target rustdoc (`ci-rustc-sysroot` vs `stage2`). In that case, we need to ensure this // explicitly to make sure it ends up in the stage2 sysroot. - builder.ensure(compile::Std::new(compiler, target)); - builder.ensure(compile::Rustc::new(compiler, target)); + let mut steps = vec![]; + steps.push(CompileStep::Std(target)); + steps.push(CompileStep::Rustc(target, None)); let mut cargo = tool::prepare_tool_cargo( builder, @@ -2774,6 +2777,7 @@ impl Step for CrateRustdoc { "src/tools/rustdoc", SourceType::InTree, &[], + steps, ); if self.host.contains("musl") { cargo.arg("'-Ctarget-feature=-crt-static'"); @@ -2855,7 +2859,6 @@ impl Step for CrateRustdocJsonTypes { // `compiler`, then it would cause rustdoc to be built *again*, which // isn't really necessary. let compiler = builder.compiler_for(builder.top_stage, target, target); - builder.ensure(compile::Rustc::new(compiler, target)); let cargo = tool::prepare_tool_cargo( builder, @@ -2866,6 +2869,7 @@ impl Step for CrateRustdocJsonTypes { "src/rustdoc-json-types", SourceType::InTree, &[], + vec![CompileStep::Rustc(target, None)], ); // FIXME: this looks very wrong, libtest doesn't accept `-C` arguments and the quotes are fishy. @@ -3090,7 +3094,6 @@ impl Step for TierCheck { /// Tests the Platform Support page in the rustc book. fn run(self, builder: &Builder<'_>) { - builder.ensure(compile::Std::new(self.compiler, self.compiler.host)); let mut cargo = tool::prepare_tool_cargo( builder, self.compiler, @@ -3100,6 +3103,7 @@ impl Step for TierCheck { "src/tools/tier-check", SourceType::InTree, &[], + vec![CompileStep::Std(self.compiler.host)], ); cargo.arg(builder.src.join("src/doc/rustc/src/platform-support.md")); cargo.arg(builder.rustc(self.compiler)); @@ -3172,6 +3176,7 @@ impl Step for RustInstaller { "src/tools/rust-installer", SourceType::InTree, &[], + vec![], ); let _guard = builder.msg( @@ -3549,8 +3554,9 @@ impl Step for TestFloatParse { let path = self.path.to_str().unwrap(); let crate_name = self.path.components().last().unwrap().as_os_str().to_str().unwrap(); + let mut steps = vec![]; if !builder.download_rustc() { - builder.ensure(compile::Std::new(compiler, self.host)); + steps.push(CompileStep::Std(self.host)); } // Run any unit tests in the crate @@ -3563,6 +3569,7 @@ impl Step for TestFloatParse { path, SourceType::InTree, &[], + steps, ); run_cargo_test( @@ -3586,6 +3593,7 @@ impl Step for TestFloatParse { path, SourceType::InTree, &[], + vec![], ); cargo_run.arg("--"); diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index f1a10c3296e91..61b8fc8267b20 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -3,8 +3,8 @@ use std::{env, fs}; use build_helper::git::get_closest_merge_commit; -use crate::core::build_steps::compile; use crate::core::build_steps::toolstate::ToolState; +use crate::core::build_steps::{compile, doc}; use crate::core::builder; use crate::core::builder::{Builder, Cargo as CargoCommand, RunConfig, ShouldRun, Step}; use crate::core::config::TargetSelection; @@ -60,6 +60,14 @@ impl Builder<'_> { } } +pub enum CompileStep { + Std(TargetSelection), + Rustc(TargetSelection, Option), + Cargo(TargetSelection), + RustFmt(TargetSelection), + Clippy(TargetSelection), +} + impl Step for ToolBuild { type Output = PathBuf; @@ -76,13 +84,14 @@ impl Step for ToolBuild { let target = self.target; let mut tool = self.tool; let path = self.path; + let mut steps = vec![]; match self.mode { Mode::ToolRustc => { - builder.ensure(compile::Std::new(compiler, compiler.host)); - builder.ensure(compile::Rustc::new(compiler, target)); + steps.push(CompileStep::Std(compiler.host)); + steps.push(CompileStep::Rustc(target, None)); } - Mode::ToolStd => builder.ensure(compile::Std::new(compiler, target)), + Mode::ToolStd => steps.push(CompileStep::Std(target)), Mode::ToolBootstrap => {} // uses downloaded stage0 compiler libs _ => panic!("unexpected Mode for tool build"), } @@ -96,7 +105,9 @@ impl Step for ToolBuild { path, self.source_type, &self.extra_features, + steps, ); + if !self.allow_features.is_empty() { cargo.allow_features(self.allow_features); } @@ -142,9 +153,38 @@ pub fn prepare_tool_cargo( path: &str, source_type: SourceType, extra_features: &[String], + steps: Vec, ) -> CargoCommand { let mut cargo = builder::Cargo::new(builder, compiler, mode, source_type, target, cmd_kind); + for s in steps { + match s { + CompileStep::Std(target) => { + builder.ensure(compile::Std::new(compiler, target)); + } + CompileStep::Rustc(target, stage) => { + if let Some(s) = stage { + builder.ensure(doc::Rustc::new(s, target, builder)); + } else { + builder.ensure(compile::Rustc::new(compiler, target)); + } + } + CompileStep::Cargo(target) => { + builder.ensure(Cargo { compiler, target }); + } + CompileStep::RustFmt(target) => { + builder.ensure(Rustfmt { + compiler, + target, + extra_features: extra_features.to_vec(), + }); + } + CompileStep::Clippy(target) => { + builder.ensure(Clippy { compiler, target, extra_features: Vec::new() }); + } + } + } + let dir = builder.src.join(path); cargo.arg("--manifest-path").arg(dir.join("Cargo.toml")); @@ -642,10 +682,10 @@ impl Step for Rustdoc { // When using `download-rustc` and a stage0 build_compiler, copying rustc doesn't actually // build stage0 libstd (because the libstd in sysroot has the wrong ABI). Explicitly build - // it. - builder.ensure(compile::Std::new(build_compiler, target_compiler.host)); - builder.ensure(compile::Rustc::new(build_compiler, target_compiler.host)); - + let steps = vec![ + CompileStep::Std(target_compiler.host), + CompileStep::Rustc(target_compiler.host, None), + ]; // The presence of `target_compiler` ensures that the necessary libraries (codegen backends, // compiler libraries, ...) are built. Rustdoc does not require the presence of any // libraries within sysroot_libdir (i.e., rustlib), though doctests may want it (since @@ -668,6 +708,7 @@ impl Step for Rustdoc { "src/tools/rustdoc", SourceType::InTree, features.as_slice(), + steps, ); let _guard = builder.msg_tool( @@ -888,11 +929,11 @@ impl Step for LlvmBitcodeLinker { fn run(self, builder: &Builder<'_>) -> PathBuf { let bin_name = "llvm-bitcode-linker"; - + let mut steps = vec![]; // If enabled, use ci-rustc and skip building the in-tree compiler. if !builder.download_rustc() { - builder.ensure(compile::Std::new(self.compiler, self.compiler.host)); - builder.ensure(compile::Rustc::new(self.compiler, self.target)); + steps.push(CompileStep::Std(self.compiler.host)); + steps.push(CompileStep::Rustc(self.target, None)); } let cargo = prepare_tool_cargo( @@ -904,6 +945,7 @@ impl Step for LlvmBitcodeLinker { "src/tools/llvm-bitcode-linker", SourceType::InTree, &self.extra_features, + steps, ); let _guard = builder.msg_tool(