From 3ec2abc2f466dd466634056b8ad9d65d519e9fd0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 15 Aug 2025 20:43:41 +0200 Subject: [PATCH] Fix staging in `x install` --- src/bootstrap/src/core/build_steps/dist.rs | 45 +++++----- src/bootstrap/src/core/build_steps/install.rs | 84 +++++++++---------- src/bootstrap/src/core/builder/tests.rs | 37 ++++---- 3 files changed, 81 insertions(+), 85 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 7689a155bd1..f5829f89e1d 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -762,6 +762,29 @@ pub struct Std { pub target: TargetSelection, } +impl Std { + pub fn new(builder: &Builder<'_>, target: TargetSelection) -> Self { + // This is a build time optimization for running just `x dist rust-std` (without + // `x dist rustc`). + // If we know that we will be uplifting a stage2+ library from stage 1 anyway, + // there is no point in building a stage2 rustc, which will then not do anything (because + // the stdlib will be uplifted). + let top_stage = builder.top_stage; + let stage = if top_stage > 1 + && compile::Std::should_be_uplifted_from_stage_1(builder, top_stage, target) + { + builder.info(&format!( + "Note: stage {top_stage} library for `{}` would be uplifted from stage 1, so stage was downgraded from {top_stage} to 1 to avoid needless compiler build(s)", + target + )); + 1 + } else { + top_stage + }; + Std { build_compiler: builder.compiler(stage, builder.config.host_target), target } + } +} + impl Step for Std { type Output = Option; const DEFAULT: bool = true; @@ -771,27 +794,7 @@ impl Step for Std { } fn make_run(run: RunConfig<'_>) { - // This is a build time optimization for running just `x dist rust-std` (without - // `x dist rustc`). - // If we know that we will be uplifting a stage2+ library from stage 1 anyway, - // there is no point in building a stage2 rustc, which will then not do anything (because - // the stdlib will be uplifted). - let top_stage = run.builder.top_stage; - let stage = if top_stage > 1 - && compile::Std::should_be_uplifted_from_stage_1(run.builder, top_stage, run.target) - { - run.builder.info(&format!( - "Note: stage {top_stage} library for `{}` would be uplifted from stage 1, so stage was downgraded from {top_stage} to 1 to avoid needless compiler build(s)", - run.target - )); - 1 - } else { - top_stage - }; - run.builder.ensure(Std { - build_compiler: run.builder.compiler(stage, run.builder.config.host_target), - target: run.target, - }); + run.builder.ensure(Std::new(run.builder, run.target)); } fn run(self, builder: &Builder<'_>) -> Option { diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs index ee8f864d2c2..ce68dbf5a20 100644 --- a/src/bootstrap/src/core/build_steps/install.rs +++ b/src/bootstrap/src/core/build_steps/install.rs @@ -65,17 +65,14 @@ fn is_dir_writable_for_user(dir: &Path) -> bool { fn install_sh( builder: &Builder<'_>, package: &str, - stage: u32, - host: Option, + build_compiler: impl Into>, + target: Option, tarball: &GeneratedTarball, ) { - let _guard = builder.msg( - Kind::Install, - package, - None, - (host.unwrap_or(builder.host_target), stage), - host, - ); + let _guard = match build_compiler.into() { + Some(build_compiler) => builder.msg(Kind::Install, package, None, build_compiler, target), + None => builder.msg_unstaged(Kind::Install, package, target.unwrap_or(builder.host_target)), + }; let prefix = default_path(&builder.config.prefix, "/usr/local"); let sysconfdir = prefix.join(default_path(&builder.config.sysconfdir, "/etc")); @@ -167,10 +164,10 @@ macro_rules! install { IS_HOST: $IS_HOST:expr, $run_item:block $(, $c:ident)*;)+) => { $( - #[derive(Debug, Clone, Hash, PartialEq, Eq)] + #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct $name { - pub compiler: Compiler, - pub target: TargetSelection, + build_compiler: Compiler, + target: TargetSelection, } impl $name { @@ -194,7 +191,7 @@ macro_rules! install { fn make_run(run: RunConfig<'_>) { run.builder.ensure($name { - compiler: run.builder.compiler(run.builder.top_stage, run.builder.config.host_target), + build_compiler: run.builder.compiler(run.builder.top_stage - 1, run.builder.config.host_target), target: run.target, }); } @@ -209,96 +206,95 @@ macro_rules! install { install!((self, builder, _config), Docs, path = "src/doc", _config.docs, IS_HOST: false, { let tarball = builder.ensure(dist::Docs { host: self.target }).expect("missing docs"); - install_sh(builder, "docs", self.compiler.stage, Some(self.target), &tarball); + install_sh(builder, "docs", self.build_compiler, Some(self.target), &tarball); }; Std, path = "library/std", true, IS_HOST: false, { // `expect` should be safe, only None when host != build, but this // only runs when host == build - let tarball = builder.ensure(dist::Std { - build_compiler: self.compiler, - target: self.target - }).expect("missing std"); - install_sh(builder, "std", self.compiler.stage, Some(self.target), &tarball); + let std = dist::Std::new(builder, self.target); + let build_compiler = std.build_compiler; + let tarball = builder.ensure(std).expect("missing std"); + install_sh(builder, "std", build_compiler, Some(self.target), &tarball); }; Cargo, alias = "cargo", Self::should_build(_config), IS_HOST: true, { let tarball = builder - .ensure(dist::Cargo { build_compiler: self.compiler, target: self.target }) + .ensure(dist::Cargo { build_compiler: self.build_compiler, target: self.target }) .expect("missing cargo"); - install_sh(builder, "cargo", self.compiler.stage, Some(self.target), &tarball); + install_sh(builder, "cargo", self.build_compiler, Some(self.target), &tarball); }; RustAnalyzer, alias = "rust-analyzer", Self::should_build(_config), IS_HOST: true, { if let Some(tarball) = - builder.ensure(dist::RustAnalyzer { compilers: RustcPrivateCompilers::from_build_compiler(builder, self.compiler, self.target), target: self.target }) + builder.ensure(dist::RustAnalyzer { compilers: RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, self.target), target: self.target }) { - install_sh(builder, "rust-analyzer", self.compiler.stage, Some(self.target), &tarball); + install_sh(builder, "rust-analyzer", self.build_compiler, Some(self.target), &tarball); } else { builder.info( - &format!("skipping Install rust-analyzer stage{} ({})", self.compiler.stage, self.target), + &format!("skipping Install rust-analyzer stage{} ({})", self.build_compiler.stage + 1, self.target), ); } }; Clippy, alias = "clippy", Self::should_build(_config), IS_HOST: true, { let tarball = builder - .ensure(dist::Clippy { compilers: RustcPrivateCompilers::from_build_compiler(builder, self.compiler, self.target), target: self.target }) + .ensure(dist::Clippy { compilers: RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, self.target), target: self.target }) .expect("missing clippy"); - install_sh(builder, "clippy", self.compiler.stage, Some(self.target), &tarball); + install_sh(builder, "clippy", self.build_compiler, Some(self.target), &tarball); }; Miri, alias = "miri", Self::should_build(_config), IS_HOST: true, { - if let Some(tarball) = builder.ensure(dist::Miri { compilers: RustcPrivateCompilers::from_build_compiler(builder, self.compiler, self.target) , target: self.target }) { - install_sh(builder, "miri", self.compiler.stage, Some(self.target), &tarball); + if let Some(tarball) = builder.ensure(dist::Miri { compilers: RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, self.target) , target: self.target }) { + install_sh(builder, "miri", self.build_compiler, Some(self.target), &tarball); } else { // Miri is only available on nightly builder.info( - &format!("skipping Install miri stage{} ({})", self.compiler.stage, self.target), + &format!("skipping Install miri stage{} ({})", self.build_compiler.stage + 1, self.target), ); } }; LlvmTools, alias = "llvm-tools", _config.llvm_tools_enabled && _config.llvm_enabled(_config.host_target), IS_HOST: true, { if let Some(tarball) = builder.ensure(dist::LlvmTools { target: self.target }) { - install_sh(builder, "llvm-tools", self.compiler.stage, Some(self.target), &tarball); + install_sh(builder, "llvm-tools", None, Some(self.target), &tarball); } else { builder.info( - &format!("skipping llvm-tools stage{} ({}): external LLVM", self.compiler.stage, self.target), + &format!("skipping llvm-tools ({}): external LLVM", self.target), ); } }; Rustfmt, alias = "rustfmt", Self::should_build(_config), IS_HOST: true, { if let Some(tarball) = builder.ensure(dist::Rustfmt { - compilers: RustcPrivateCompilers::from_build_compiler(builder, self.compiler, self.target), + compilers: RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, self.target), target: self.target }) { - install_sh(builder, "rustfmt", self.compiler.stage, Some(self.target), &tarball); + install_sh(builder, "rustfmt", self.build_compiler, Some(self.target), &tarball); } else { builder.info( - &format!("skipping Install Rustfmt stage{} ({})", self.compiler.stage, self.target), + &format!("skipping Install Rustfmt stage{} ({})", self.build_compiler.stage + 1, self.target), ); } }; Rustc, path = "compiler/rustc", true, IS_HOST: true, { let tarball = builder.ensure(dist::Rustc { - target_compiler: builder.compiler(builder.top_stage, self.target), + target_compiler: builder.compiler(self.build_compiler.stage + 1, self.target), }); - install_sh(builder, "rustc", self.compiler.stage, Some(self.target), &tarball); + install_sh(builder, "rustc", self.build_compiler, Some(self.target), &tarball); }; RustcCodegenCranelift, alias = "rustc-codegen-cranelift", Self::should_build(_config), IS_HOST: true, { if let Some(tarball) = builder.ensure(dist::CraneliftCodegenBackend { - compilers: RustcPrivateCompilers::new(builder, builder.top_stage, self.target), + compilers: RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, self.target), target: self.target }) { - install_sh(builder, "rustc-codegen-cranelift", self.compiler.stage, Some(self.target), &tarball); + install_sh(builder, "rustc-codegen-cranelift", self.build_compiler, Some(self.target), &tarball); } else { builder.info( &format!("skipping Install CodegenBackend(\"cranelift\") stage{} ({})", - self.compiler.stage, self.target), + self.build_compiler.stage + 1, self.target), ); } }; LlvmBitcodeLinker, alias = "llvm-bitcode-linker", Self::should_build(_config), IS_HOST: true, { - if let Some(tarball) = builder.ensure(dist::LlvmBitcodeLinker { build_compiler: self.compiler, target: self.target }) { - install_sh(builder, "llvm-bitcode-linker", self.compiler.stage, Some(self.target), &tarball); + if let Some(tarball) = builder.ensure(dist::LlvmBitcodeLinker { build_compiler: self.build_compiler, target: self.target }) { + install_sh(builder, "llvm-bitcode-linker", self.build_compiler, Some(self.target), &tarball); } else { builder.info( - &format!("skipping llvm-bitcode-linker stage{} ({})", self.compiler.stage, self.target), + &format!("skipping llvm-bitcode-linker stage{} ({})", self.build_compiler.stage + 1, self.target), ); } }; @@ -306,7 +302,7 @@ install!((self, builder, _config), #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Src { - pub stage: u32, + stage: u32, } impl Step for Src { @@ -326,6 +322,6 @@ impl Step for Src { fn run(self, builder: &Builder<'_>) { let tarball = builder.ensure(dist::Src); - install_sh(builder, "src", self.stage, None, &tarball); + install_sh(builder, "src", None, None, &tarball); } } diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 18c23c5f689..1471b5df846 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2310,18 +2310,18 @@ mod snapshot { [build] llvm [build] rustc 0 -> rustc 1 [build] rustc 0 -> WasmComponentLd 1 - [build] rustc 1 -> std 1 - [build] rustc 1 -> rustc 2 - [build] rustc 1 -> WasmComponentLd 2 [build] rustc 0 -> UnstableBookGen 1 [build] rustc 0 -> Rustbook 1 [doc] unstable-book (book) + [build] rustc 1 -> std 1 [doc] book (book) [doc] book/first-edition (book) [doc] book/second-edition (book) [doc] book/2018-edition (book) [build] rustdoc 1 [doc] rustc 1 -> standalone 2 + [build] rustc 1 -> rustc 2 + [build] rustc 1 -> WasmComponentLd 2 [build] rustdoc 2 [doc] rustc 2 -> std 2 crates=[alloc,compiler_builtins,core,panic_abort,panic_unwind,proc_macro,rustc-std-workspace-core,std,std_detect,sysroot,test,unwind] [build] rustc 1 -> error-index 2 @@ -2340,26 +2340,23 @@ mod snapshot { [doc] rustc 1 -> releases 2 [build] rustc 0 -> RustInstaller 1 [dist] docs - [build] rustc 2 -> std 2 - [dist] rustc 2 -> std 2 + [dist] rustc 1 -> std 1 [build] rustc 1 -> rust-analyzer-proc-macro-srv 2 [build] rustc 0 -> GenerateCopyright 1 [dist] rustc - [build] rustc 2 -> cargo 3 - [dist] rustc 2 -> cargo 3 - [build] rustc 2 -> rustc 3 - [build] rustc 2 -> WasmComponentLd 3 - [build] rustc 2 -> rust-analyzer 3 - [dist] rustc 2 -> rust-analyzer 3 - [build] rustc 2 -> rustfmt 3 - [build] rustc 2 -> cargo-fmt 3 - [dist] rustc 2 -> rustfmt 3 - [build] rustc 2 -> clippy-driver 3 - [build] rustc 2 -> cargo-clippy 3 - [dist] rustc 2 -> clippy 3 - [build] rustc 2 -> miri 3 - [build] rustc 2 -> cargo-miri 3 - [dist] rustc 2 -> miri 3 + [build] rustc 1 -> cargo 2 + [dist] rustc 1 -> cargo 2 + [build] rustc 1 -> rust-analyzer 2 + [dist] rustc 1 -> rust-analyzer 2 + [build] rustc 1 -> rustfmt 2 + [build] rustc 1 -> cargo-fmt 2 + [dist] rustc 1 -> rustfmt 2 + [build] rustc 1 -> clippy-driver 2 + [build] rustc 1 -> cargo-clippy 2 + [dist] rustc 1 -> clippy 2 + [build] rustc 1 -> miri 2 + [build] rustc 1 -> cargo-miri 2 + [dist] rustc 1 -> miri 2 [dist] src <> "); }