diff options
| author | Jakub Beránek <berykubik@gmail.com> | 2025-07-22 12:03:55 +0200 |
|---|---|---|
| committer | Jakub Beránek <berykubik@gmail.com> | 2025-08-01 15:44:53 +0200 |
| commit | 6d562b2c747c61a15de50c056e809c5202dff5bf (patch) | |
| tree | 710d51af7b1c030ec0e9dda14d5df3b728dd4fb7 | |
| parent | 2f3bfff0511088bfb84e84b15273be5a3d00f2f3 (diff) | |
| download | rust-6d562b2c747c61a15de50c056e809c5202dff5bf.tar.gz rust-6d562b2c747c61a15de50c056e809c5202dff5bf.zip | |
Implement `RustcPrivateCompilers` to unify building of `rustc_private` tools
| -rw-r--r-- | src/bootstrap/src/core/build_steps/compile.rs | 1 | ||||
| -rw-r--r-- | src/bootstrap/src/core/build_steps/dist.rs | 83 | ||||
| -rw-r--r-- | src/bootstrap/src/core/build_steps/install.rs | 8 | ||||
| -rw-r--r-- | src/bootstrap/src/core/build_steps/run.rs | 14 | ||||
| -rw-r--r-- | src/bootstrap/src/core/build_steps/test.rs | 94 | ||||
| -rw-r--r-- | src/bootstrap/src/core/build_steps/tool.rs | 264 | ||||
| -rw-r--r-- | src/bootstrap/src/core/builder/mod.rs | 23 | ||||
| -rw-r--r-- | src/bootstrap/src/core/builder/tests.rs | 62 | ||||
| -rw-r--r-- | src/bootstrap/src/lib.rs | 7 |
9 files changed, 287 insertions, 269 deletions
diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 59541bf12de..488217549d9 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -1635,6 +1635,7 @@ impl Step for CodegenBackend { let target = self.target; let backend = self.backend; + // FIXME: migrate to RustcPrivateCompilers builder.ensure(Rustc::new(compiler, target)); if builder.config.keep_stage.contains(&compiler.stage) { diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index f1f112896a9..2d504cbd55a 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -20,7 +20,7 @@ use object::read::archive::ArchiveFile; use tracing::instrument; use crate::core::build_steps::doc::DocumentationFormat; -use crate::core::build_steps::tool::{self, Tool}; +use crate::core::build_steps::tool::{self, RustcPrivateCompilers, Tool}; use crate::core::build_steps::vendor::{VENDOR_DIR, Vendor}; use crate::core::build_steps::{compile, llvm}; use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step, StepMetadata}; @@ -431,13 +431,14 @@ impl Step for Rustc { let ra_proc_macro_srv_compiler = builder.compiler_for(compiler.stage, builder.config.host_target, compiler.host); - builder.ensure(compile::Rustc::new(ra_proc_macro_srv_compiler, compiler.host)); + let compilers = RustcPrivateCompilers::from_build_compiler( + builder, + ra_proc_macro_srv_compiler, + compiler.host, + ); if let Some(ra_proc_macro_srv) = builder.ensure_if_default( - tool::RustAnalyzerProcMacroSrv { - compiler: ra_proc_macro_srv_compiler, - target: compiler.host, - }, + tool::RustAnalyzerProcMacroSrv::from_compilers(compilers), builder.kind, ) { let dst = image.join("libexec"); @@ -1228,7 +1229,7 @@ impl Step for Cargo { #[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)] pub struct RustAnalyzer { - pub compiler: Compiler, + pub build_compiler: Compiler, pub target: TargetSelection, } @@ -1244,7 +1245,7 @@ impl Step for RustAnalyzer { fn make_run(run: RunConfig<'_>) { run.builder.ensure(RustAnalyzer { - compiler: run.builder.compiler_for( + build_compiler: run.builder.compiler_for( run.builder.top_stage, run.builder.config.host_target, run.target, @@ -1254,12 +1255,11 @@ impl Step for RustAnalyzer { } fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { - let compiler = self.compiler; let target = self.target; + let compilers = + RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, self.target); - builder.ensure(compile::Rustc::new(compiler, target)); - - let rust_analyzer = builder.ensure(tool::RustAnalyzer { compiler, target }); + let rust_analyzer = builder.ensure(tool::RustAnalyzer::from_compilers(compilers)); let mut tarball = Tarball::new(builder, "rust-analyzer", &target.triple); tarball.set_overlay(OverlayKind::RustAnalyzer); @@ -1270,9 +1270,9 @@ impl Step for RustAnalyzer { } } -#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Clippy { - pub compiler: Compiler, + pub build_compiler: Compiler, pub target: TargetSelection, } @@ -1288,7 +1288,7 @@ impl Step for Clippy { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Clippy { - compiler: run.builder.compiler_for( + build_compiler: run.builder.compiler_for( run.builder.top_stage, run.builder.config.host_target, run.target, @@ -1298,16 +1298,15 @@ impl Step for Clippy { } fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { - let compiler = self.compiler; let target = self.target; - - builder.ensure(compile::Rustc::new(compiler, target)); + let compilers = + RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, target); // Prepare the image directory // We expect clippy to build, because we've exited this step above if tool // state for clippy isn't testing. - let clippy = builder.ensure(tool::Clippy { compiler, target }); - let cargoclippy = builder.ensure(tool::CargoClippy { compiler, target }); + let clippy = builder.ensure(tool::Clippy::from_compilers(compilers)); + let cargoclippy = builder.ensure(tool::CargoClippy::from_compilers(compilers)); let mut tarball = Tarball::new(builder, "clippy", &target.triple); tarball.set_overlay(OverlayKind::Clippy); @@ -1319,9 +1318,9 @@ impl Step for Clippy { } } -#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Miri { - pub compiler: Compiler, + pub build_compiler: Compiler, pub target: TargetSelection, } @@ -1337,7 +1336,7 @@ impl Step for Miri { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Miri { - compiler: run.builder.compiler_for( + build_compiler: run.builder.compiler_for( run.builder.top_stage, run.builder.config.host_target, run.target, @@ -1354,15 +1353,12 @@ impl Step for Miri { return None; } - let compiler = self.compiler; - let target = self.target; - - builder.ensure(compile::Rustc::new(compiler, target)); - - let miri = builder.ensure(tool::Miri { compiler, target }); - let cargomiri = builder.ensure(tool::CargoMiri { compiler, target }); + let compilers = + RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, self.target); + let miri = builder.ensure(tool::Miri::from_compilers(compilers)); + let cargomiri = builder.ensure(tool::CargoMiri::from_compilers(compilers)); - let mut tarball = Tarball::new(builder, "miri", &target.triple); + let mut tarball = Tarball::new(builder, "miri", &self.target.triple); tarball.set_overlay(OverlayKind::Miri); tarball.is_preview(true); tarball.add_file(&miri.tool_path, "bin", FileType::Executable); @@ -1466,9 +1462,9 @@ impl Step for CodegenBackend { } } -#[derive(Debug, PartialOrd, Ord, Clone, Hash, PartialEq, Eq)] +#[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Rustfmt { - pub compiler: Compiler, + pub build_compiler: Compiler, pub target: TargetSelection, } @@ -1484,7 +1480,7 @@ impl Step for Rustfmt { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Rustfmt { - compiler: run.builder.compiler_for( + build_compiler: run.builder.compiler_for( run.builder.top_stage, run.builder.config.host_target, run.target, @@ -1494,14 +1490,13 @@ impl Step for Rustfmt { } fn run(self, builder: &Builder<'_>) -> Option<GeneratedTarball> { - let compiler = self.compiler; - let target = self.target; + let compilers = + RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, self.target); - builder.ensure(compile::Rustc::new(compiler, target)); + let rustfmt = builder.ensure(tool::Rustfmt::from_compilers(compilers)); + let cargofmt = builder.ensure(tool::Cargofmt::from_compilers(compilers)); - let rustfmt = builder.ensure(tool::Rustfmt { compiler, target }); - let cargofmt = builder.ensure(tool::Cargofmt { compiler, target }); - let mut tarball = Tarball::new(builder, "rustfmt", &target.triple); + let mut tarball = Tarball::new(builder, "rustfmt", &self.target.triple); tarball.set_overlay(OverlayKind::Rustfmt); tarball.is_preview(true); tarball.add_file(&rustfmt.tool_path, "bin", FileType::Executable); @@ -1569,11 +1564,11 @@ impl Step for Extended { add_component!("rust-docs" => Docs { host: target }); add_component!("rust-json-docs" => JsonDocs { host: target }); add_component!("cargo" => Cargo { compiler, target }); - add_component!("rustfmt" => Rustfmt { compiler, target }); - add_component!("rust-analyzer" => RustAnalyzer { compiler, target }); + add_component!("rustfmt" => Rustfmt { build_compiler: compiler, target }); + add_component!("rust-analyzer" => RustAnalyzer { build_compiler: compiler, target }); add_component!("llvm-components" => LlvmTools { target }); - add_component!("clippy" => Clippy { compiler, target }); - add_component!("miri" => Miri { compiler, target }); + add_component!("clippy" => Clippy { build_compiler: compiler, target }); + add_component!("miri" => Miri { build_compiler: compiler, target }); add_component!("analysis" => Analysis { compiler, target }); add_component!("rustc-codegen-cranelift" => CodegenBackend { compiler: builder.compiler(stage, target), diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs index 4513a138e19..2427b019129 100644 --- a/src/bootstrap/src/core/build_steps/install.rs +++ b/src/bootstrap/src/core/build_steps/install.rs @@ -221,7 +221,7 @@ install!((self, builder, _config), }; RustAnalyzer, alias = "rust-analyzer", Self::should_build(_config), only_hosts: true, { if let Some(tarball) = - builder.ensure(dist::RustAnalyzer { compiler: self.compiler, target: self.target }) + builder.ensure(dist::RustAnalyzer { build_compiler: self.compiler, target: self.target }) { install_sh(builder, "rust-analyzer", self.compiler.stage, Some(self.target), &tarball); } else { @@ -232,12 +232,12 @@ install!((self, builder, _config), }; Clippy, alias = "clippy", Self::should_build(_config), only_hosts: true, { let tarball = builder - .ensure(dist::Clippy { compiler: self.compiler, target: self.target }) + .ensure(dist::Clippy { build_compiler: self.compiler, target: self.target }) .expect("missing clippy"); install_sh(builder, "clippy", self.compiler.stage, Some(self.target), &tarball); }; Miri, alias = "miri", Self::should_build(_config), only_hosts: true, { - if let Some(tarball) = builder.ensure(dist::Miri { compiler: self.compiler, target: self.target }) { + if let Some(tarball) = builder.ensure(dist::Miri { build_compiler: self.compiler, target: self.target }) { install_sh(builder, "miri", self.compiler.stage, Some(self.target), &tarball); } else { // Miri is only available on nightly @@ -257,7 +257,7 @@ install!((self, builder, _config), }; Rustfmt, alias = "rustfmt", Self::should_build(_config), only_hosts: true, { if let Some(tarball) = builder.ensure(dist::Rustfmt { - compiler: self.compiler, + build_compiler: self.compiler, target: self.target }) { install_sh(builder, "rustfmt", self.compiler.stage, Some(self.target), &tarball); diff --git a/src/bootstrap/src/core/build_steps/run.rs b/src/bootstrap/src/core/build_steps/run.rs index b2293fdd9b5..984744b5678 100644 --- a/src/bootstrap/src/core/build_steps/run.rs +++ b/src/bootstrap/src/core/build_steps/run.rs @@ -9,7 +9,7 @@ use clap_complete::{Generator, shells}; use crate::core::build_steps::dist::distdir; use crate::core::build_steps::test; -use crate::core::build_steps::tool::{self, SourceType, Tool}; +use crate::core::build_steps::tool::{self, RustcPrivateCompilers, SourceType, Tool}; use crate::core::build_steps::vendor::{Vendor, default_paths_to_vendor}; use crate::core::builder::{Builder, Kind, RunConfig, ShouldRun, Step}; use crate::core::config::TargetSelection; @@ -135,13 +135,13 @@ impl Step for Miri { } // This compiler runs on the host, we'll just use it for the target. - let target_compiler = builder.compiler(stage, target); - let miri_build = builder.ensure(tool::Miri { compiler: target_compiler, target }); - // Rustc tools are off by one stage, so use the build compiler to run miri. + let compilers = RustcPrivateCompilers::new(builder, stage, target); + let miri_build = builder.ensure(tool::Miri::from_compilers(compilers)); let host_compiler = miri_build.build_compiler; // Get a target sysroot for Miri. - let miri_sysroot = test::Miri::build_miri_sysroot(builder, target_compiler, target); + let miri_sysroot = + test::Miri::build_miri_sysroot(builder, compilers.link_compiler(), target); // # Run miri. // Running it via `cargo run` as that figures out the right dylib path. @@ -465,8 +465,8 @@ impl Step for Rustfmt { std::process::exit(1); } - let compiler = builder.compiler(stage, host); - let rustfmt_build = builder.ensure(tool::Rustfmt { compiler, target: host }); + let compilers = RustcPrivateCompilers::new(builder, stage, host); + let rustfmt_build = builder.ensure(tool::Rustfmt::from_compilers(compilers)); let mut rustfmt = tool::prepare_tool_cargo( builder, diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 1884dec89f9..f725e458c4a 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -17,7 +17,9 @@ use crate::core::build_steps::gcc::{Gcc, add_cg_gcc_cargo_flags}; use crate::core::build_steps::llvm::get_llvm_version; use crate::core::build_steps::run::get_completion_paths; use crate::core::build_steps::synthetic_targets::MirOptPanicAbortSyntheticTarget; -use crate::core::build_steps::tool::{self, COMPILETEST_ALLOW_FEATURES, SourceType, Tool}; +use crate::core::build_steps::tool::{ + self, COMPILETEST_ALLOW_FEATURES, RustcPrivateCompilers, SourceType, Tool, +}; use crate::core::build_steps::toolstate::ToolState; use crate::core::build_steps::{compile, dist, llvm}; use crate::core::builder::{ @@ -364,8 +366,7 @@ impl Step for Cargo { #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct RustAnalyzer { - stage: u32, - host: TargetSelection, + compilers: RustcPrivateCompilers, } impl Step for RustAnalyzer { @@ -378,19 +379,18 @@ impl Step for RustAnalyzer { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Self { stage: run.builder.top_stage, host: run.target }); + run.builder.ensure(Self { + compilers: RustcPrivateCompilers::new( + run.builder, + run.builder.top_stage, + run.builder.host_target, + ), + }); } /// Runs `cargo test` for rust-analyzer fn run(self, builder: &Builder<'_>) { - let stage = self.stage; - let host = self.host; - let compiler = builder.compiler(stage, host); - let compiler = tool::get_tool_rustc_build_compiler(builder, compiler); - - // 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 host = self.compilers.target(); let workspace_path = "src/tools/rust-analyzer"; // until the whole RA test suite runs on `i686`, we only run @@ -398,7 +398,7 @@ impl Step for RustAnalyzer { let crate_path = "src/tools/rust-analyzer/crates/proc-macro-srv"; let mut cargo = tool::prepare_tool_cargo( builder, - compiler, + self.compilers.build_compiler(), Mode::ToolRustc, host, Kind::Test, @@ -425,8 +425,7 @@ impl Step for RustAnalyzer { /// Runs `cargo test` for rustfmt. #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Rustfmt { - stage: u32, - host: TargetSelection, + compilers: RustcPrivateCompilers, } impl Step for Rustfmt { @@ -438,36 +437,39 @@ impl Step for Rustfmt { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Rustfmt { stage: run.builder.top_stage, host: run.target }); + run.builder.ensure(Rustfmt { + compilers: RustcPrivateCompilers::new( + run.builder, + run.builder.top_stage, + run.builder.host_target, + ), + }); } /// Runs `cargo test` for rustfmt. fn run(self, builder: &Builder<'_>) { - let stage = self.stage; - let host = self.host; - let compiler = builder.compiler(stage, host); - - let tool_result = builder.ensure(tool::Rustfmt { compiler, target: self.host }); - let compiler = tool_result.build_compiler; + let tool_result = builder.ensure(tool::Rustfmt::from_compilers(self.compilers)); + let build_compiler = tool_result.build_compiler; + let target = self.compilers.target(); let mut cargo = tool::prepare_tool_cargo( builder, - compiler, + build_compiler, Mode::ToolRustc, - host, + target, Kind::Test, "src/tools/rustfmt", SourceType::InTree, &[], ); - let dir = testdir(builder, compiler.host); + let dir = testdir(builder, target); t!(fs::create_dir_all(&dir)); cargo.env("RUSTFMT_TEST_DIR", dir); cargo.add_rustc_lib_path(builder); - run_cargo_test(cargo, &[], &[], "rustfmt", host, builder); + run_cargo_test(cargo, &[], &[], "rustfmt", target, builder); } } @@ -542,12 +544,14 @@ impl Step for Miri { } // This compiler runs on the host, we'll just use it for the target. - let target_compiler = builder.compiler(stage, host); + let compilers = RustcPrivateCompilers::new(builder, stage, host); // Build our tools. - let miri = builder.ensure(tool::Miri { compiler: target_compiler, target: host }); + let miri = builder.ensure(tool::Miri::from_compilers(compilers)); // the ui tests also assume cargo-miri has been built - builder.ensure(tool::CargoMiri { compiler: target_compiler, target: host }); + builder.ensure(tool::CargoMiri::from_compilers(compilers)); + + let target_compiler = compilers.link_compiler(); // 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. @@ -756,7 +760,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the #[derive(Debug, Clone, PartialEq, Eq, Hash)] pub struct Clippy { - host: TargetSelection, + compilers: RustcPrivateCompilers, } impl Step for Clippy { @@ -769,23 +773,30 @@ impl Step for Clippy { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Clippy { host: run.target }); + run.builder.ensure(Clippy { + compilers: RustcPrivateCompilers::new( + run.builder, + run.builder.top_stage, + run.builder.host_target, + ), + }); } /// Runs `cargo test` for clippy. fn run(self, builder: &Builder<'_>) { - let stage = builder.top_stage; - let host = self.host; + let host = self.compilers.target(); + // We need to carefully distinguish the compiler that builds clippy, and the compiler // that is linked into the clippy being tested. `target_compiler` is the latter, // and it must also be used by clippy's test runner to build tests and their dependencies. - let target_compiler = builder.compiler(stage, host); + let compilers = self.compilers; + let target_compiler = compilers.link_compiler(); - let tool_result = builder.ensure(tool::Clippy { compiler: target_compiler, target: host }); - let tool_compiler = tool_result.build_compiler; + let tool_result = builder.ensure(tool::Clippy::from_compilers(compilers)); + let build_compiler = tool_result.build_compiler; let mut cargo = tool::prepare_tool_cargo( builder, - tool_compiler, + build_compiler, Mode::ToolRustc, host, Kind::Test, @@ -794,9 +805,10 @@ impl Step for Clippy { &[], ); - cargo.env("RUSTC_TEST_SUITE", builder.rustc(tool_compiler)); - cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(tool_compiler)); - let host_libs = builder.stage_out(tool_compiler, Mode::ToolRustc).join(builder.cargo_dir()); + cargo.env("RUSTC_TEST_SUITE", builder.rustc(build_compiler)); + cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(build_compiler)); + let host_libs = + builder.stage_out(build_compiler, Mode::ToolRustc).join(builder.cargo_dir()); cargo.env("HOST_LIBS", host_libs); // Build the standard library that the tests can use. @@ -826,7 +838,7 @@ impl Step for Clippy { let cargo = prepare_cargo_test(cargo, &[], &[], host, builder); let _guard = - builder.msg_sysroot_tool(Kind::Test, tool_compiler.stage, "clippy", host, host); + builder.msg_sysroot_tool(Kind::Test, build_compiler.stage, "clippy", host, host); // Clippy reports errors if it blessed the outputs if cargo.allow_failure().run(builder) { diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index 77d15b13165..b3e054a9d8b 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -90,11 +90,8 @@ impl Builder<'_> { pub struct ToolBuildResult { /// Artifact path of the corresponding tool that was built. pub tool_path: PathBuf, - /// Compiler used to build the tool. For non-`ToolRustc` tools this is equal to `target_compiler`. - /// For `ToolRustc` this is one stage before of the `target_compiler`. + /// Compiler used to build the tool. pub build_compiler: Compiler, - /// Target compiler passed to `Step`. - pub target_compiler: Compiler, } impl Step for ToolBuild { @@ -108,26 +105,13 @@ impl Step for ToolBuild { /// /// This will build the specified tool with the specified `host` compiler in /// `stage` into the normal cargo output directory. - fn run(mut self, builder: &Builder<'_>) -> ToolBuildResult { + fn run(self, builder: &Builder<'_>) -> ToolBuildResult { let target = self.target; let mut tool = self.tool; let path = self.path; - let target_compiler = self.build_compiler; - self.build_compiler = if self.mode == Mode::ToolRustc { - get_tool_rustc_build_compiler(builder, self.build_compiler) - } else { - self.build_compiler - }; - match self.mode { - Mode::ToolRustc => { - // If compiler was forced, its artifacts should have been prepared earlier. - if !self.build_compiler.is_forced_compiler() { - builder.std(self.build_compiler, self.build_compiler.host); - builder.ensure(compile::Rustc::new(self.build_compiler, target)); - } - } + Mode::ToolRustc => {} Mode::ToolStd => { // If compiler was forced, its artifacts should have been prepared earlier. if !self.build_compiler.is_forced_compiler() { @@ -184,8 +168,7 @@ impl Step for ToolBuild { Kind::Build, self.mode, self.tool, - // A stage N tool is built with the stage N-1 compiler. - self.build_compiler.stage + 1, + self.build_compiler.stage, &self.build_compiler.host, &self.target, ); @@ -216,7 +199,7 @@ impl Step for ToolBuild { .join(format!("lib{tool}.rlib")), }; - ToolBuildResult { tool_path, build_compiler: self.build_compiler, target_compiler } + ToolBuildResult { tool_path, build_compiler: self.build_compiler } } } } @@ -346,27 +329,6 @@ pub fn prepare_tool_cargo( cargo } -/// Handle stage-off logic for `ToolRustc` tools when necessary. -pub(crate) fn get_tool_rustc_build_compiler( - builder: &Builder<'_>, - target_compiler: Compiler, -) -> Compiler { - if target_compiler.is_forced_compiler() { - return target_compiler; - } - - if builder.download_rustc() && target_compiler.stage == 1 { - // We shouldn't drop to stage0 compiler when using CI rustc. - return builder.compiler(1, builder.config.host_target); - } - - // Similar to `compile::Assemble`, build with the previous stage's compiler. Otherwise - // we'd have stageN/bin/rustc and stageN/bin/$rustc_tool be effectively different stage - // compilers, which isn't what we want. Rustc tools should be linked in the same way as the - // compiler it's paired with, so it must be built with the previous stage compiler. - builder.compiler(target_compiler.stage.saturating_sub(1), builder.config.host_target) -} - /// Determines how to build a `ToolTarget`, i.e. which compiler should be used to compile it. /// The compiler stage is automatically bumped if we need to cross-compile a stage 1 tool. pub enum ToolTargetBuildMode { @@ -753,7 +715,6 @@ impl Step for Rustdoc { return ToolBuildResult { tool_path: builder.initial_rustdoc.clone(), build_compiler: target_compiler, - target_compiler, }; } @@ -785,11 +746,7 @@ impl Step for Rustdoc { let bin_rustdoc = bin_rustdoc(); builder.copy_link(&precompiled_rustdoc, &bin_rustdoc, FileType::Executable); - return ToolBuildResult { - tool_path: bin_rustdoc, - build_compiler: target_compiler, - target_compiler, - }; + return ToolBuildResult { tool_path: bin_rustdoc, build_compiler: target_compiler }; } } @@ -805,23 +762,23 @@ impl Step for Rustdoc { extra_features.push("jemalloc".to_string()); } - let ToolBuildResult { tool_path, build_compiler, target_compiler } = - builder.ensure(ToolBuild { - build_compiler: target_compiler, - target, - // Cargo adds a number of paths to the dylib search path on windows, which results in - // the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool" - // rustdoc a different name. - tool: "rustdoc_tool_binary", - mode: Mode::ToolRustc, - path: "src/tools/rustdoc", - source_type: SourceType::InTree, - extra_features, - allow_features: "", - cargo_args: Vec::new(), - artifact_kind: ToolArtifactKind::Binary, - }); + let ToolBuildResult { tool_path, build_compiler } = builder.ensure(ToolBuild { + build_compiler: target_compiler, + target, + // Cargo adds a number of paths to the dylib search path on windows, which results in + // the wrong rustdoc being executed. To avoid the conflicting rustdocs, we name the "tool" + // rustdoc a different name. + tool: "rustdoc_tool_binary", + mode: Mode::ToolRustc, + path: "src/tools/rustdoc", + source_type: SourceType::InTree, + extra_features, + allow_features: "", + cargo_args: Vec::new(), + artifact_kind: ToolArtifactKind::Binary, + }); + // FIXME: handle the build/target compiler split here somehow // don't create a stage0-sysroot/bin directory. if target_compiler.stage > 0 { if builder.config.rust_debuginfo_level_tools == DebuginfoLevel::None { @@ -831,9 +788,9 @@ impl Step for Rustdoc { } let bin_rustdoc = bin_rustdoc(); builder.copy_link(&tool_path, &bin_rustdoc, FileType::Executable); - ToolBuildResult { tool_path: bin_rustdoc, build_compiler, target_compiler } + ToolBuildResult { tool_path: bin_rustdoc, build_compiler } } else { - ToolBuildResult { tool_path, build_compiler, target_compiler } + ToolBuildResult { tool_path, build_compiler } } } @@ -1075,8 +1032,13 @@ impl Step for WasmComponentLd { #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct RustAnalyzer { - pub compiler: Compiler, - pub target: TargetSelection, + compilers: RustcPrivateCompilers, +} + +impl RustAnalyzer { + pub fn from_compilers(compilers: RustcPrivateCompilers) -> Self { + Self { compilers } + } } impl RustAnalyzer { @@ -1095,15 +1057,16 @@ impl Step for RustAnalyzer { fn make_run(run: RunConfig<'_>) { run.builder.ensure(RustAnalyzer { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target), - target: run.target, + compilers: RustcPrivateCompilers::new(run.builder, run.builder.top_stage, run.target), }); } fn run(self, builder: &Builder<'_>) -> ToolBuildResult { + let build_compiler = self.compilers.build_compiler; + let target = self.compilers.target(); builder.ensure(ToolBuild { - build_compiler: self.compiler, - target: self.target, + build_compiler, + target, tool: "rust-analyzer", mode: Mode::ToolRustc, path: "src/tools/rust-analyzer", @@ -1116,18 +1079,22 @@ impl Step for RustAnalyzer { } fn metadata(&self) -> Option<StepMetadata> { - // FIXME: fix staging logic Some( - StepMetadata::build("rust-analyzer", self.target) - .built_by(self.compiler.with_stage(self.compiler.stage - 1)), + StepMetadata::build("rust-analyzer", self.compilers.target()) + .built_by(self.compilers.build_compiler), ) } } #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct RustAnalyzerProcMacroSrv { - pub compiler: Compiler, - pub target: TargetSelection, + compilers: RustcPrivateCompilers, +} + +impl RustAnalyzerProcMacroSrv { + pub fn from_compilers(compilers: RustcPrivateCompilers) -> Self { + Self { compilers } + } } impl Step for RustAnalyzerProcMacroSrv { @@ -1149,15 +1116,14 @@ impl Step for RustAnalyzerProcMacroSrv { fn make_run(run: RunConfig<'_>) { run.builder.ensure(RustAnalyzerProcMacroSrv { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target), - target: run.target, + compilers: RustcPrivateCompilers::new(run.builder, run.builder.top_stage, run.target), }); } fn run(self, builder: &Builder<'_>) -> Self::Output { let tool_result = builder.ensure(ToolBuild { - build_compiler: self.compiler, - target: self.target, + build_compiler: self.compilers.build_compiler, + target: self.compilers.target(), tool: "rust-analyzer-proc-macro-srv", mode: Mode::ToolRustc, path: "src/tools/rust-analyzer/crates/proc-macro-srv-cli", @@ -1170,7 +1136,7 @@ impl Step for RustAnalyzerProcMacroSrv { // Copy `rust-analyzer-proc-macro-srv` to `<sysroot>/libexec/` // so that r-a can use it. - let libexec_path = builder.sysroot(self.compiler).join("libexec"); + let libexec_path = builder.sysroot(self.compilers.link_compiler).join("libexec"); t!(fs::create_dir_all(&libexec_path)); builder.copy_link( &tool_result.tool_path, @@ -1182,10 +1148,9 @@ impl Step for RustAnalyzerProcMacroSrv { } fn metadata(&self) -> Option<StepMetadata> { - // FIXME: fix ToolRust staging logic Some( - StepMetadata::build("rust-analyzer-proc-macro-srv", self.target) - .built_by(self.compiler.with_stage(self.compiler.stage - 1)), + StepMetadata::build("rust-analyzer-proc-macro-srv", self.compilers.target()) + .built_by(self.compilers.build_compiler), ) } } @@ -1328,6 +1293,70 @@ impl Step for LibcxxVersionTool { } } +/// Represents which compilers are involved in the compilation of a tool +/// that depends on compiler internals (`rustc_private`). +/// Their compilation looks like this: +/// +/// - `build_compiler` (stage N-1) builds `link_compiler` (stage N) to produce .rlibs +/// - These .rlibs are copied into the sysroot of `build_compiler` +/// - `build_compiler` (stage N-1) builds `<tool>` (stage N) +/// - `<tool>` links to .rlibs from `link_compiler` +/// +/// Eventually, this could also be used for .rmetas and check builds, but so far we only deal with +/// normal builds here. +#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq)] +pub struct RustcPrivateCompilers { + /// Compiler that builds the tool and that builds `link_compiler`. + build_compiler: Compiler, + /// Compiler to which .rlib artifacts the tool links to. + /// The host target of this compiler corresponds to the target of the tool. + link_compiler: Compiler, +} + +impl RustcPrivateCompilers { + /// Create compilers for a `rustc_private` tool with the given `stage` and for the given + /// `target`. + pub fn new(builder: &Builder<'_>, stage: u32, target: TargetSelection) -> Self { + assert!(stage > 0); + + let build_compiler = if builder.download_rustc() && stage == 1 { + // We shouldn't drop to stage0 compiler when using CI rustc. + builder.compiler(1, builder.config.host_target) + } else { + builder.compiler(stage - 1, builder.config.host_target) + }; + + // This is the compiler we'll link to + // FIXME: make 100% sure that `link_compiler` was indeed built with `build_compiler`... + let link_compiler = builder.compiler(stage, target); + + Self { build_compiler, link_compiler } + } + + /// Create rustc tool compilers from the build compiler. + pub fn from_build_compiler( + builder: &Builder<'_>, + build_compiler: Compiler, + target: TargetSelection, + ) -> Self { + let link_compiler = builder.compiler(build_compiler.stage + 1, target); + Self { build_compiler, link_compiler } + } + + pub fn build_compiler(&self) -> Compiler { + self.build_compiler + } + + pub fn link_compiler(&self) -> Compiler { + self.link_compiler + } + + /// Target of the tool being compiled + pub fn target(&self) -> TargetSelection { + self.link_compiler.host + } +} + /// Creates a step that builds an extended `Mode::ToolRustc` tool /// and installs it into the sysroot of a corresponding compiler. macro_rules! tool_rustc_extended { @@ -1344,8 +1373,15 @@ macro_rules! tool_rustc_extended { ) => { #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct $name { - pub compiler: Compiler, - pub target: TargetSelection, + compilers: RustcPrivateCompilers, + } + + impl $name { + pub fn from_compilers(compilers: RustcPrivateCompilers) -> Self { + Self { + compilers, + } + } } impl Step for $name { @@ -1364,17 +1400,15 @@ macro_rules! tool_rustc_extended { fn make_run(run: RunConfig<'_>) { run.builder.ensure($name { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target), - target: run.target, + compilers: RustcPrivateCompilers::new(run.builder, run.builder.top_stage, run.target), }); } fn run(self, builder: &Builder<'_>) -> ToolBuildResult { - let Self { compiler, target } = self; + let Self { compilers } = self; build_extended_rustc_tool( builder, - compiler, - target, + compilers, $tool_name, $path, None $( .or(Some(&$add_bins_to_sysroot)) )?, @@ -1384,11 +1418,9 @@ macro_rules! tool_rustc_extended { } fn metadata(&self) -> Option<StepMetadata> { - // FIXME: refactor extended tool steps to make the build_compiler explicit, - // it is offset by one now for rustc tools Some( - StepMetadata::build($tool_name, self.target) - .built_by(self.compiler.with_stage(self.compiler.stage.saturating_sub(1))) + StepMetadata::build($tool_name, self.compilers.target()) + .built_by(self.compilers.build_compiler) ) } } @@ -1422,36 +1454,36 @@ fn should_run_extended_rustc_tool<'a>( #[expect(clippy::too_many_arguments)] // silence overeager clippy lint fn build_extended_rustc_tool( builder: &Builder<'_>, - compiler: Compiler, - target: TargetSelection, + compilers: RustcPrivateCompilers, tool_name: &'static str, path: &'static str, add_bins_to_sysroot: Option<&[&str]>, add_features: Option<fn(&Builder<'_>, TargetSelection, &mut Vec<String>)>, cargo_args: Option<&[&'static str]>, ) -> ToolBuildResult { + let target = compilers.target(); let mut extra_features = Vec::new(); if let Some(func) = add_features { func(builder, target, &mut extra_features); } - let ToolBuildResult { tool_path, build_compiler, target_compiler } = - builder.ensure(ToolBuild { - build_compiler: compiler, - target, - tool: tool_name, - mode: Mode::ToolRustc, - path, - extra_features, - source_type: SourceType::InTree, - allow_features: "", - cargo_args: cargo_args.unwrap_or_default().iter().map(|s| String::from(*s)).collect(), - artifact_kind: ToolArtifactKind::Binary, - }); - + let build_compiler = compilers.build_compiler; + let ToolBuildResult { tool_path, .. } = builder.ensure(ToolBuild { + build_compiler, + target, + tool: tool_name, + mode: Mode::ToolRustc, + path, + extra_features, + source_type: SourceType::InTree, + allow_features: "", + cargo_args: cargo_args.unwrap_or_default().iter().map(|s| String::from(*s)).collect(), + artifact_kind: ToolArtifactKind::Binary, + }); + + let target_compiler = compilers.link_compiler; if let Some(add_bins_to_sysroot) = add_bins_to_sysroot && !add_bins_to_sysroot.is_empty() - && target_compiler.stage > 0 { let bindir = builder.sysroot(target_compiler).join("bin"); t!(fs::create_dir_all(&bindir)); @@ -1463,9 +1495,9 @@ fn build_extended_rustc_tool( // Return a path into the bin dir. let path = bindir.join(exe(tool_name, target_compiler.host)); - ToolBuildResult { tool_path: path, build_compiler, target_compiler } + ToolBuildResult { tool_path: path, build_compiler } } else { - ToolBuildResult { tool_path, build_compiler, target_compiler } + ToolBuildResult { tool_path, build_compiler } } } diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 1a28c170048..b30c460d5f1 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -16,6 +16,7 @@ use tracing::instrument; pub use self::cargo::{Cargo, cargo_profile_var}; pub use crate::Compiler; use crate::core::build_steps::compile::{Std, StdLink}; +use crate::core::build_steps::tool::RustcPrivateCompilers; use crate::core::build_steps::{ check, clean, clippy, compile, dist, doc, gcc, install, llvm, run, setup, test, tool, vendor, }; @@ -1555,10 +1556,13 @@ You have to build a stage1 compiler for `{}` first, and then use it to build a s return cmd; } - let _ = - self.ensure(tool::Clippy { compiler: run_compiler, target: self.build.host_target }); - let cargo_clippy = self - .ensure(tool::CargoClippy { compiler: run_compiler, target: self.build.host_target }); + // FIXME: double check that `run_compiler`'s stage is what we want to use + let compilers = + RustcPrivateCompilers::new(self, run_compiler.stage, self.build.host_target); + assert_eq!(run_compiler, compilers.link_compiler()); + + let _ = self.ensure(tool::Clippy::from_compilers(compilers)); + let cargo_clippy = self.ensure(tool::CargoClippy::from_compilers(compilers)); let mut dylib_path = helpers::dylib_path(); dylib_path.insert(0, self.sysroot(run_compiler).join("lib")); @@ -1570,11 +1574,14 @@ You have to build a stage1 compiler for `{}` first, and then use it to build a s pub fn cargo_miri_cmd(&self, run_compiler: Compiler) -> BootstrapCommand { assert!(run_compiler.stage > 0, "miri can not be invoked at stage 0"); + + let compilers = + RustcPrivateCompilers::new(self, run_compiler.stage, self.build.host_target); + assert_eq!(run_compiler, compilers.link_compiler()); + // Prepare the tools - let miri = - self.ensure(tool::Miri { compiler: run_compiler, target: self.build.host_target }); - let cargo_miri = - self.ensure(tool::CargoMiri { compiler: run_compiler, target: self.build.host_target }); + let miri = self.ensure(tool::Miri::from_compilers(compilers)); + let cargo_miri = self.ensure(tool::CargoMiri::from_compilers(compilers)); // Invoke cargo-miri, make sure it can find miri and cargo. let mut cmd = command(cargo_miri.tool_path); cmd.env("MIRI", &miri.tool_path); diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index d6f61f87863..77832c5dc31 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -569,36 +569,6 @@ fn test_is_builder_target() { } } -#[test] -fn test_get_tool_rustc_compiler() { - let mut config = configure("build", &[], &[]); - config.download_rustc_commit = None; - let build = Build::new(config); - let builder = Builder::new(&build); - - let target_triple_1 = TargetSelection::from_user(TEST_TRIPLE_1); - - let compiler = Compiler::new(2, target_triple_1); - let expected = Compiler::new(1, target_triple_1); - let actual = tool::get_tool_rustc_build_compiler(&builder, compiler); - assert_eq!(expected, actual); - - let compiler = Compiler::new(1, target_triple_1); - let expected = Compiler::new(0, target_triple_1); - let actual = tool::get_tool_rustc_build_compiler(&builder, compiler); - assert_eq!(expected, actual); - - let mut config = configure("build", &[], &[]); - config.download_rustc_commit = Some("".to_owned()); - let build = Build::new(config); - let builder = Builder::new(&build); - - let compiler = Compiler::new(1, target_triple_1); - let expected = Compiler::new(1, target_triple_1); - let actual = tool::get_tool_rustc_build_compiler(&builder, compiler); - assert_eq!(expected, actual); -} - /// When bootstrap detects a step dependency cycle (which is a bug), its panic /// message should show the actual steps on the stack, not just several copies /// of `Any { .. }`. @@ -1097,19 +1067,19 @@ mod snapshot { [dist] docs <host> [doc] std 2 <host> crates=[] [dist] mingw <host> - [build] rustc 0 <host> -> rust-analyzer-proc-macro-srv 1 <host> + [build] rustc 1 <host> -> rust-analyzer-proc-macro-srv 2 <host> [build] rustc 0 <host> -> GenerateCopyright 1 <host> [dist] rustc <host> [dist] rustc 1 <host> -> std 1 <host> [dist] src <> [build] rustc 0 <host> -> cargo 1 <host> - [build] rustc 0 <host> -> rust-analyzer 1 <host> - [build] rustc 0 <host> -> rustfmt 1 <host> - [build] rustc 0 <host> -> cargo-fmt 1 <host> - [build] rustc 0 <host> -> clippy-driver 1 <host> - [build] rustc 0 <host> -> cargo-clippy 1 <host> - [build] rustc 0 <host> -> miri 1 <host> - [build] rustc 0 <host> -> cargo-miri 1 <host> + [build] rustc 1 <host> -> rust-analyzer 2 <host> + [build] rustc 1 <host> -> rustfmt 2 <host> + [build] rustc 1 <host> -> cargo-fmt 2 <host> + [build] rustc 1 <host> -> clippy-driver 2 <host> + [build] rustc 1 <host> -> cargo-clippy 2 <host> + [build] rustc 1 <host> -> miri 2 <host> + [build] rustc 1 <host> -> cargo-miri 2 <host> "); } @@ -1290,19 +1260,19 @@ mod snapshot { [build] rustc 1 <host> -> rustc 2 <target1> [build] rustc 1 <host> -> WasmComponentLd 2 <target1> [build] rustdoc 1 <target1> - [build] rustc 0 <host> -> rust-analyzer-proc-macro-srv 1 <target1> + [build] rustc 1 <host> -> rust-analyzer-proc-macro-srv 2 <target1> [build] rustc 0 <host> -> GenerateCopyright 1 <host> [dist] rustc <target1> [dist] rustc 1 <host> -> std 1 <target1> [dist] src <> [build] rustc 0 <host> -> cargo 1 <target1> - [build] rustc 0 <host> -> rust-analyzer 1 <target1> - [build] rustc 0 <host> -> rustfmt 1 <target1> - [build] rustc 0 <host> -> cargo-fmt 1 <target1> - [build] rustc 0 <host> -> clippy-driver 1 <target1> - [build] rustc 0 <host> -> cargo-clippy 1 <target1> - [build] rustc 0 <host> -> miri 1 <target1> - [build] rustc 0 <host> -> cargo-miri 1 <target1> + [build] rustc 1 <host> -> rust-analyzer 2 <target1> + [build] rustc 1 <host> -> rustfmt 2 <target1> + [build] rustc 1 <host> -> cargo-fmt 2 <target1> + [build] rustc 1 <host> -> clippy-driver 2 <target1> + [build] rustc 1 <host> -> cargo-clippy 2 <target1> + [build] rustc 1 <host> -> miri 2 <target1> + [build] rustc 1 <host> -> cargo-miri 2 <target1> [build] rustc 1 <host> -> LlvmBitcodeLinker 2 <target1> "); } diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 011b52df97b..7c7638c4b76 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -1160,17 +1160,18 @@ impl Build { fn msg_sysroot_tool( &self, action: impl Into<Kind>, - stage: u32, + build_stage: u32, what: impl Display, host: TargetSelection, target: TargetSelection, ) -> Option<gha::Group> { let action = action.into().description(); let msg = |fmt| format!("{action} {what} {fmt}"); + let msg = if host == target { - msg(format_args!("(stage{stage} -> stage{}, {target})", stage + 1)) + msg(format_args!("(stage{build_stage} -> stage{}, {target})", build_stage + 1)) } else { - msg(format_args!("(stage{stage}:{host} -> stage{}:{target})", stage + 1)) + msg(format_args!("(stage{build_stage}:{host} -> stage{}:{target})", build_stage + 1)) }; self.group(&msg) } |
