From cf6612286e9c9a826925592fb0256e11e0c2aff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 15 Aug 2025 21:05:57 +0200 Subject: [PATCH 01/30] Re-add missing `clippy` tests --- src/bootstrap/src/core/builder/tests.rs | 124 ++++++++++++++++++++++++ 1 file changed, 124 insertions(+) diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 2afba25ae5922..2d4c8fb48dbf3 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2126,6 +2126,130 @@ mod snapshot { [doc] rustc 1 -> reference (book) 2 "); } + + #[test] + fn clippy_ci() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("clippy") + .path("ci") + .stage(2) + .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 1 -> std 1 + [build] rustc 0 -> clippy-driver 1 + [build] rustc 0 -> cargo-clippy 1 + [clippy] rustc 1 -> bootstrap 2 + [clippy] rustc 1 -> std 1 + [clippy] rustc 1 -> rustc 2 + [check] rustc 1 -> rustc 2 + [clippy] rustc 1 -> rustc_codegen_gcc 2 + "); + } + + #[test] + fn clippy_compiler_stage1() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("clippy") + .path("compiler") + .render_steps(), @r" + [build] llvm + [clippy] rustc 0 -> rustc 1 + "); + } + + #[test] + fn clippy_compiler_stage2() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("clippy") + .path("compiler") + .stage(2) + .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 1 -> std 1 + [build] rustc 0 -> clippy-driver 1 + [build] rustc 0 -> cargo-clippy 1 + [clippy] rustc 1 -> rustc 2 + "); + } + + #[test] + fn clippy_std_stage1() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("clippy") + .path("std") + .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 0 -> clippy-driver 1 + [build] rustc 0 -> cargo-clippy 1 + [clippy] rustc 1 -> std 1 + "); + } + + #[test] + fn clippy_std_stage2() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("clippy") + .path("std") + .stage(2) + .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 1 -> std 1 + [build] rustc 1 -> rustc 2 + [build] rustc 1 -> clippy-driver 2 + [build] rustc 1 -> cargo-clippy 2 + [clippy] rustc 2 -> std 2 + "); + } + + #[test] + fn clippy_miri_stage1() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("clippy") + .path("miri") + .stage(1) + .render_steps(), @r" + [build] llvm + [check] rustc 0 -> rustc 1 + [clippy] rustc 0 -> miri 1 + "); + } + + #[test] + fn clippy_miri_stage2() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("clippy") + .path("miri") + .stage(2) + .render_steps(), @r" + [build] llvm + [build] rustc 0 -> rustc 1 + [build] rustc 1 -> std 1 + [check] rustc 1 -> rustc 2 + [build] rustc 0 -> clippy-driver 1 + [build] rustc 0 -> cargo-clippy 1 + [clippy] rustc 1 -> miri 2 + "); + } + + #[test] + fn clippy_bootstrap() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("clippy") + .path("bootstrap") + .render_steps(), @"[clippy] rustc 0 -> bootstrap 1 "); + } } struct ExecutedSteps { From 7cdee3927e1e5e7b2e1e32929e940abe9b20823d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 12 Aug 2025 12:15:36 +0200 Subject: [PATCH 02/30] Forbid running dist steps on stage 0 --- src/bootstrap/src/core/config/config.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index f579bdd847f66..485960f425664 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1041,6 +1041,10 @@ impl Config { eprintln!("ERROR: cannot run clippy on stage 0. Use at least stage 1."); exit!(1); } + (0, Subcommand::Dist { .. }) => { + eprintln!("ERROR: cannot dist anything on stage 0. Use at least stage 1."); + exit!(1); + } _ => {} } From 391bb133f5cdd85901aa374521a4333be38f6dd3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 12 Aug 2025 10:28:13 +0200 Subject: [PATCH 03/30] Rename `default_doc` to `run_default_doc_steps` and remove unused argument --- src/bootstrap/src/core/build_steps/dist.rs | 4 ++-- src/bootstrap/src/core/build_steps/test.rs | 4 ++-- src/bootstrap/src/core/builder/mod.rs | 5 +++-- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index daac75c03e2d7..5066640f8dc78 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -75,7 +75,7 @@ impl Step for Docs { /// Builds the `rust-docs` installer component. fn run(self, builder: &Builder<'_>) -> Option { let host = self.host; - builder.default_doc(&[]); + builder.run_default_doc_steps(); let dest = "share/doc/rust/html"; @@ -154,7 +154,7 @@ impl Step for RustcDocs { /// Builds the `rustc-docs` installer component. fn run(self, builder: &Builder<'_>) -> Option { let host = self.host; - builder.default_doc(&[]); + builder.run_default_doc_steps(); let mut tarball = Tarball::new(builder, "rustc-docs", &host.triple); tarball.set_product_name("Rustc Documentation"); diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 269e7da8d7b24..ef7bdbbcddc9f 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -153,7 +153,7 @@ You can skip linkcheck with --skip src/tools/linkchecker" } // Build all the default documentation. - builder.default_doc(&[]); + builder.run_default_doc_steps(); // Build the linkchecker before calling `msg`, since GHA doesn't support nested groups. let linkchecker = builder.tool_cmd(Tool::Linkchecker); @@ -208,7 +208,7 @@ impl Step for HtmlCheck { panic!("Cannot run html-check tests"); } // Ensure that a few different kinds of documentation are available. - builder.default_doc(&[]); + builder.run_default_doc_steps(); builder.ensure(crate::core::build_steps::doc::Rustc::for_stage( builder, builder.top_stage, diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 40460bf168dc0..5e55df67f5c15 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -1308,8 +1308,9 @@ impl<'a> Builder<'a> { self.run_step_descriptions(&Builder::get_step_descriptions(self.kind), &self.paths); } - pub fn default_doc(&self, paths: &[PathBuf]) { - self.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), paths); + /// Run all default documentation steps to build documentation. + pub fn run_default_doc_steps(&self) { + self.run_step_descriptions(&Builder::get_step_descriptions(Kind::Doc), &[]); } pub fn doc_rust_lang_org_channel(&self) -> String { From a1f67b6b2f5533461c6c7b06353cd584ec1ad5e2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 12 Aug 2025 11:17:20 +0200 Subject: [PATCH 04/30] Document the `rustc-docs` step --- src/bootstrap/src/core/build_steps/dist.rs | 27 ++++++++++++++-------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 5066640f8dc78..3ac7a5d476bea 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -75,6 +75,9 @@ impl Step for Docs { /// Builds the `rust-docs` installer component. fn run(self, builder: &Builder<'_>) -> Option { let host = self.host; + // FIXME: explicitly enumerate the steps that should be executed here, and gather their + // documentation, rather than running all default steps and then read their output + // from a shared directory. builder.run_default_doc_steps(); let dest = "share/doc/rust/html"; @@ -132,13 +135,20 @@ impl Step for JsonDocs { } } +/// Builds the `rustc-docs` installer component. +/// Apart from the documentation of the `rustc_*` crates, it also includes the documentation of +/// various in-tree helper tools (bootstrap, build_helper, tidy), +/// and also rustc_private tools like rustdoc, clippy, miri or rustfmt. +/// +/// It is currently hosted at https://doc.rust-lang.org/nightly/nightly-rustc #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct RustcDocs { - pub host: TargetSelection, + target: TargetSelection, } impl Step for RustcDocs { - type Output = Option; + type Output = GeneratedTarball; + const DEFAULT: bool = true; const IS_HOST: bool = true; @@ -148,18 +158,17 @@ impl Step for RustcDocs { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(RustcDocs { host: run.target }); + run.builder.ensure(RustcDocs { target: run.target }); } - /// Builds the `rustc-docs` installer component. - fn run(self, builder: &Builder<'_>) -> Option { - let host = self.host; + fn run(self, builder: &Builder<'_>) -> Self::Output { + let target = self.target; builder.run_default_doc_steps(); - let mut tarball = Tarball::new(builder, "rustc-docs", &host.triple); + let mut tarball = Tarball::new(builder, "rustc-docs", &target.triple); tarball.set_product_name("Rustc Documentation"); - tarball.add_bulk_dir(builder.compiler_doc_out(host), "share/doc/rust/html/rustc"); - Some(tarball.generate()) + tarball.add_bulk_dir(builder.compiler_doc_out(target), "share/doc/rust/html/rustc"); + tarball.generate() } } From 1537ad6772310eceac277cb01d381e5351f8dc84 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 12 Aug 2025 11:19:34 +0200 Subject: [PATCH 05/30] Small refactor of `Mingw` step --- src/bootstrap/src/core/build_steps/dist.rs | 24 +++++++++++----------- 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 3ac7a5d476bea..6a2d70c32781f 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -363,9 +363,13 @@ fn get_cc_search_dirs( (bin_path, lib_path) } +/// Builds the `rust-mingw` installer component. +/// +/// This contains all the bits and pieces to run the MinGW Windows targets +/// without any extra installed software (e.g., we bundle gcc, libraries, etc.). #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Mingw { - pub host: TargetSelection, + target: TargetSelection, } impl Step for Mingw { @@ -377,29 +381,25 @@ impl Step for Mingw { } fn make_run(run: RunConfig<'_>) { - run.builder.ensure(Mingw { host: run.target }); + run.builder.ensure(Mingw { target: run.target }); } - /// Builds the `rust-mingw` installer component. - /// - /// This contains all the bits and pieces to run the MinGW Windows targets - /// without any extra installed software (e.g., we bundle gcc, libraries, etc). fn run(self, builder: &Builder<'_>) -> Option { - let host = self.host; - if !host.ends_with("pc-windows-gnu") || !builder.config.dist_include_mingw_linker { + let target = self.target; + if !target.ends_with("pc-windows-gnu") || !builder.config.dist_include_mingw_linker { return None; } - let mut tarball = Tarball::new(builder, "rust-mingw", &host.triple); + let mut tarball = Tarball::new(builder, "rust-mingw", &target.triple); tarball.set_product_name("Rust MinGW"); - make_win_dist(tarball.image_dir(), host, builder); + make_win_dist(tarball.image_dir(), target, builder); Some(tarball.generate()) } fn metadata(&self) -> Option { - Some(StepMetadata::dist("mingw", self.host)) + Some(StepMetadata::dist("mingw", self.target)) } } @@ -1625,7 +1625,7 @@ impl Step for Extended { tarballs.push(builder.ensure(Std { compiler, target }).expect("missing std")); if target.is_windows_gnu() { - tarballs.push(builder.ensure(Mingw { host: target }).expect("missing mingw")); + tarballs.push(builder.ensure(Mingw { target }).expect("missing mingw")); } add_component!("rust-docs" => Docs { host: target }); From 9bd83171842123bbb1a153ef13543661827366ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 12 Aug 2025 11:45:30 +0200 Subject: [PATCH 06/30] Refactor and document the `Rustc` dist step --- src/bootstrap/src/core/build_steps/dist.rs | 75 ++++++++++--------- src/bootstrap/src/core/build_steps/install.rs | 2 +- 2 files changed, 42 insertions(+), 35 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 6a2d70c32781f..78154b62f16a2 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -403,13 +403,24 @@ impl Step for Mingw { } } +/// Creates the `rustc` installer component. +/// +/// This includes: +/// - The compiler and LLVM. +/// - Debugger scripts. +/// - Various helper tools, e.g. LLD or Rust Analyzer proc-macro server (if enabled). +/// - The licenses of all code used by the compiler. +/// +/// It does not include any standard library. #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Rustc { - pub compiler: Compiler, + /// This is the compiler that we will *ship* in this dist step. + pub target_compiler: Compiler, } impl Step for Rustc { type Output = GeneratedTarball; + const DEFAULT: bool = true; const IS_HOST: bool = true; @@ -418,19 +429,19 @@ impl Step for Rustc { } fn make_run(run: RunConfig<'_>) { - run.builder - .ensure(Rustc { compiler: run.builder.compiler(run.builder.top_stage, run.target) }); + run.builder.ensure(Rustc { + target_compiler: run.builder.compiler(run.builder.top_stage, run.target), + }); } - /// Creates the `rustc` installer component. fn run(self, builder: &Builder<'_>) -> GeneratedTarball { - let compiler = self.compiler; - let host = self.compiler.host; + let target_compiler = self.target_compiler; + let target = self.target_compiler.host; - let tarball = Tarball::new(builder, "rustc", &host.triple); + let tarball = Tarball::new(builder, "rustc", &target.triple); // Prepare the rustc "image", what will actually end up getting installed - prepare_image(builder, compiler, tarball.image_dir()); + prepare_image(builder, target_compiler, tarball.image_dir()); // On MinGW we've got a few runtime DLL dependencies that we need to // include. @@ -439,16 +450,16 @@ impl Step for Rustc { // anything requiring us to distribute a license, but it's likely the // install will *also* include the rust-mingw package, which also needs // licenses, so to be safe we just include it here in all MinGW packages. - if host.contains("pc-windows-gnu") && builder.config.dist_include_mingw_linker { - runtime_dll_dist(tarball.image_dir(), host, builder); + if target.contains("pc-windows-gnu") && builder.config.dist_include_mingw_linker { + runtime_dll_dist(tarball.image_dir(), target, builder); tarball.add_dir(builder.src.join("src/etc/third-party"), "share/doc"); } return tarball.generate(); - fn prepare_image(builder: &Builder<'_>, compiler: Compiler, image: &Path) { - let host = compiler.host; - let src = builder.sysroot(compiler); + fn prepare_image(builder: &Builder<'_>, target_compiler: Compiler, image: &Path) { + let host = target_compiler.host; + let src = builder.sysroot(target_compiler); // Copy rustc binary t!(fs::create_dir_all(image.join("bin"))); @@ -461,17 +472,11 @@ impl Step for Rustc { .as_ref() .is_none_or(|tools| tools.iter().any(|tool| tool == "rustdoc")) { - let rustdoc = builder.rustdoc_for_compiler(compiler); + let rustdoc = builder.rustdoc_for_compiler(target_compiler); builder.install(&rustdoc, &image.join("bin"), FileType::Executable); } - let ra_proc_macro_srv_compiler = - builder.compiler_for(compiler.stage, builder.config.host_target, compiler.host); - let compilers = RustcPrivateCompilers::from_build_compiler( - builder, - ra_proc_macro_srv_compiler, - compiler.host, - ); + let compilers = RustcPrivateCompilers::from_target_compiler(builder, target_compiler); if let Some(ra_proc_macro_srv) = builder.ensure_if_default( tool::RustAnalyzerProcMacroSrv::from_compilers(compilers), @@ -481,11 +486,11 @@ impl Step for Rustc { builder.install(&ra_proc_macro_srv.tool_path, &dst, FileType::Executable); } - let libdir_relative = builder.libdir_relative(compiler); + let libdir_relative = builder.libdir_relative(target_compiler); // Copy runtime DLLs needed by the compiler if libdir_relative.to_str() != Some("bin") { - let libdir = builder.rustc_libdir(compiler); + let libdir = builder.rustc_libdir(target_compiler); for entry in builder.read_dir(&libdir) { // A safeguard that we will not ship libgccjit.so from the libdir, in case the // GCC codegen backend is enabled by default. @@ -519,8 +524,8 @@ impl Step for Rustc { // Copy over lld if it's there if builder.config.lld_enabled { - let src_dir = builder.sysroot_target_bindir(compiler, host); - let rust_lld = exe("rust-lld", compiler.host); + let src_dir = builder.sysroot_target_bindir(target_compiler, host); + let rust_lld = exe("rust-lld", target_compiler.host); builder.copy_link( &src_dir.join(&rust_lld), &dst_dir.join(&rust_lld), @@ -530,7 +535,7 @@ impl Step for Rustc { let self_contained_lld_dst_dir = dst_dir.join("gcc-ld"); t!(fs::create_dir(&self_contained_lld_dst_dir)); for name in crate::LLD_FILE_NAMES { - let exe_name = exe(name, compiler.host); + let exe_name = exe(name, target_compiler.host); builder.copy_link( &self_contained_lld_src_dir.join(&exe_name), &self_contained_lld_dst_dir.join(&exe_name), @@ -539,10 +544,12 @@ impl Step for Rustc { } } - if builder.config.llvm_enabled(compiler.host) && builder.config.llvm_tools_enabled { - let src_dir = builder.sysroot_target_bindir(compiler, host); - let llvm_objcopy = exe("llvm-objcopy", compiler.host); - let rust_objcopy = exe("rust-objcopy", compiler.host); + if builder.config.llvm_enabled(target_compiler.host) + && builder.config.llvm_tools_enabled + { + let src_dir = builder.sysroot_target_bindir(target_compiler, host); + let llvm_objcopy = exe("llvm-objcopy", target_compiler.host); + let rust_objcopy = exe("rust-objcopy", target_compiler.host); builder.copy_link( &src_dir.join(&llvm_objcopy), &dst_dir.join(&rust_objcopy), @@ -551,8 +558,8 @@ impl Step for Rustc { } if builder.tool_enabled("wasm-component-ld") { - let src_dir = builder.sysroot_target_bindir(compiler, host); - let ld = exe("wasm-component-ld", compiler.host); + let src_dir = builder.sysroot_target_bindir(target_compiler, host); + let ld = exe("wasm-component-ld", target_compiler.host); builder.copy_link(&src_dir.join(&ld), &dst_dir.join(&ld), FileType::Executable); } @@ -599,7 +606,7 @@ impl Step for Rustc { } fn metadata(&self) -> Option { - Some(StepMetadata::dist("rustc", self.compiler.host)) + Some(StepMetadata::dist("rustc", self.target_compiler.host)) } } @@ -1621,7 +1628,7 @@ impl Step for Extended { // upgrades rustc was upgraded before rust-std. To avoid rustc clobbering // the std files during uninstall. To do this ensure that rustc comes // before rust-std in the list below. - tarballs.push(builder.ensure(Rustc { compiler: target_compiler })); + tarballs.push(builder.ensure(Rustc { target_compiler })); tarballs.push(builder.ensure(Std { compiler, target }).expect("missing std")); if target.is_windows_gnu() { diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs index 4457258e9cdd0..92e5084d4908b 100644 --- a/src/bootstrap/src/core/build_steps/install.rs +++ b/src/bootstrap/src/core/build_steps/install.rs @@ -275,7 +275,7 @@ install!((self, builder, _config), }; Rustc, path = "compiler/rustc", true, IS_HOST: true, { let tarball = builder.ensure(dist::Rustc { - compiler: builder.compiler(builder.top_stage, self.target), + target_compiler: builder.compiler(builder.top_stage, self.target), }); install_sh(builder, "rustc", self.compiler.stage, Some(self.target), &tarball); }; From f8b3c566cc9b27816efa17a21365d36dd55cd71f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 12 Aug 2025 11:47:26 +0200 Subject: [PATCH 07/30] Refactor and document the `DebuggerScripts` dist step --- src/bootstrap/src/core/build_steps/dist.rs | 23 +++++++++++----------- src/bootstrap/src/core/build_steps/test.rs | 2 +- 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 78154b62f16a2..29e4a608c3ae9 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -458,7 +458,7 @@ impl Step for Rustc { return tarball.generate(); fn prepare_image(builder: &Builder<'_>, target_compiler: Compiler, image: &Path) { - let host = target_compiler.host; + let target = target_compiler.host; let src = builder.sysroot(target_compiler); // Copy rustc binary @@ -517,14 +517,14 @@ impl Step for Rustc { // components like the llvm tools and LLD. LLD is included below and // tools/LLDB come later, so let's just throw it in the rustc // component for now. - maybe_install_llvm_runtime(builder, host, image); + maybe_install_llvm_runtime(builder, target, image); - let dst_dir = image.join("lib/rustlib").join(host).join("bin"); + let dst_dir = image.join("lib/rustlib").join(target).join("bin"); t!(fs::create_dir_all(&dst_dir)); // Copy over lld if it's there if builder.config.lld_enabled { - let src_dir = builder.sysroot_target_bindir(target_compiler, host); + let src_dir = builder.sysroot_target_bindir(target_compiler, target); let rust_lld = exe("rust-lld", target_compiler.host); builder.copy_link( &src_dir.join(&rust_lld), @@ -547,7 +547,7 @@ impl Step for Rustc { if builder.config.llvm_enabled(target_compiler.host) && builder.config.llvm_tools_enabled { - let src_dir = builder.sysroot_target_bindir(target_compiler, host); + let src_dir = builder.sysroot_target_bindir(target_compiler, target); let llvm_objcopy = exe("llvm-objcopy", target_compiler.host); let rust_objcopy = exe("rust-objcopy", target_compiler.host); builder.copy_link( @@ -558,7 +558,7 @@ impl Step for Rustc { } if builder.tool_enabled("wasm-component-ld") { - let src_dir = builder.sysroot_target_bindir(target_compiler, host); + let src_dir = builder.sysroot_target_bindir(target_compiler, target); let ld = exe("wasm-component-ld", target_compiler.host); builder.copy_link(&src_dir.join(&ld), &dst_dir.join(&ld), FileType::Executable); } @@ -580,7 +580,7 @@ impl Step for Rustc { } // Debugger scripts - builder.ensure(DebuggerScripts { sysroot: image.to_owned(), host }); + builder.ensure(DebuggerScripts { sysroot: image.to_owned(), target }); // HTML copyright files let file_list = builder.ensure(super::run::GenerateCopyright); @@ -610,10 +610,12 @@ impl Step for Rustc { } } +/// Copies debugger scripts for `target` into the given compiler `sysroot`. #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct DebuggerScripts { + /// Sysroot of a compiler into which will the debugger scripts be copied to. pub sysroot: PathBuf, - pub host: TargetSelection, + pub target: TargetSelection, } impl Step for DebuggerScripts { @@ -623,16 +625,15 @@ impl Step for DebuggerScripts { run.never() } - /// Copies debugger scripts for `target` into the `sysroot` specified. fn run(self, builder: &Builder<'_>) { - let host = self.host; + let target = self.target; let sysroot = self.sysroot; let dst = sysroot.join("lib/rustlib/etc"); t!(fs::create_dir_all(&dst)); let cp_debugger_script = |file: &str| { builder.install(&builder.src.join("src/etc/").join(file), &dst, FileType::Regular); }; - if host.contains("windows-msvc") { + if target.contains("windows-msvc") { // windbg debugger scripts builder.install( &builder.src.join("src/etc/rust-windbg.cmd"), diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index ef7bdbbcddc9f..318287df08a2f 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1719,7 +1719,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the if suite == "debuginfo" { builder.ensure(dist::DebuggerScripts { sysroot: builder.sysroot(compiler).to_path_buf(), - host: target, + target, }); } if suite == "run-make" { From 502dc8df56e37477da5249245cb8074b40a4c2ce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 12 Aug 2025 12:29:14 +0200 Subject: [PATCH 08/30] Refactor `Std` dist step --- src/bootstrap/src/core/build_steps/compile.rs | 41 ++++++++++------- src/bootstrap/src/core/build_steps/dist.rs | 46 +++++++++++++------ src/bootstrap/src/core/build_steps/install.rs | 2 +- src/bootstrap/src/utils/build_stamp.rs | 6 +-- 4 files changed, 62 insertions(+), 33 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 6ca32aca345eb..7b3e5db58f807 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -96,6 +96,30 @@ impl Std { } deps } + + /// Returns true if the standard library will be uplifted from stage 1 for the given + /// `build_compiler` (which determines the stdlib stage) and `target`. + /// + /// Uplifting is enabled if we're building a stage2+ libstd, full bootstrap is + /// disabled and we have a stage1 libstd already compiled for the given target. + pub fn should_be_uplifted_from_stage_1( + builder: &Builder<'_>, + stage: u32, + target: TargetSelection, + ) -> bool { + stage > 1 + && !builder.config.full_bootstrap + // This estimates if a stage1 libstd exists for the given target. If we're not + // cross-compiling, it should definitely exist by the time we're building a stage2 + // libstd. + // Or if we are cross-compiling, and we are building a cross-compiled rustc, then that + // rustc needs to link to a cross-compiled libstd, so again we should have a stage1 + // libstd for the given target prepared. + // Even if we guess wrong in the cross-compiled case, the worst that should happen is + // that we build a fresh stage1 libstd below, and then we immediately uplift it, so we + // don't pay the libstd build cost twice. + && (target == builder.host_target || builder.config.hosts.contains(&target)) + } } impl Step for Std { @@ -193,22 +217,7 @@ impl Step for Std { // Stage of the stdlib that we're building let stage = build_compiler.stage; - // If we're building a stage2+ libstd, full bootstrap is - // disabled and we have a stage1 libstd already compiled for the given target, - // then simply uplift a previously built stage1 library. - if build_compiler.stage > 1 - && !builder.config.full_bootstrap - // This estimates if a stage1 libstd exists for the given target. If we're not - // cross-compiling, it should definitely exist by the time we're building a stage2 - // libstd. - // Or if we are cross-compiling, and we are building a cross-compiled rustc, then that - // rustc needs to link to a cross-compiled libstd, so again we should have a stage1 - // libstd for the given target prepared. - // Even if we guess wrong in the cross-compiled case, the worst that should happen is - // that we build a fresh stage1 libstd below, and then we immediately uplift it, so we - // don't pay the libstd build cost twice. - && (target == builder.host_target || builder.config.hosts.contains(&target)) - { + if Self::should_be_uplifted_from_stage_1(builder, build_compiler.stage, target) { let build_compiler_for_std_to_uplift = builder.compiler(1, builder.host_target); builder.std(build_compiler_for_std_to_uplift, target); diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 29e4a608c3ae9..5694688780bff 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -747,9 +747,16 @@ fn copy_target_libs( } } +/// Builds the standard library (`rust-std`) dist component for a given `target`. +/// This includes the standard library dynamic library file (e.g. .so/.dll), along with stdlib +/// .rlibs. +/// +/// Note that due to uplifting, we actually ship the stage 1 library +/// (built using the stage1 compiler) even with a stage 2 dist, unless `full-bootstrap` is enabled. #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Std { - pub compiler: Compiler, + /// Compiler that will build the standard library. + pub build_compiler: Compiler, pub target: TargetSelection, } @@ -762,31 +769,43 @@ 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 { - compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.host_target, - run.target, - ), + build_compiler: run.builder.compiler(stage, run.builder.config.host_target), target: run.target, }); } fn run(self, builder: &Builder<'_>) -> Option { - let compiler = self.compiler; + let build_compiler = self.build_compiler; let target = self.target; - if skip_host_target_lib(builder, compiler) { + if skip_host_target_lib(builder, build_compiler) { return None; } - builder.std(compiler, target); + builder.std(build_compiler, target); let mut tarball = Tarball::new(builder, "rust-std", &target.triple); tarball.include_target_in_component_name(true); - let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); - let stamp = build_stamp::libstd_stamp(builder, compiler_to_use, target); + let stamp = build_stamp::libstd_stamp(builder, build_compiler, target); verify_uefi_rlib_format(builder, target, &stamp); copy_target_libs(builder, target, tarball.image_dir(), &stamp); @@ -794,7 +813,7 @@ impl Step for Std { } fn metadata(&self) -> Option { - Some(StepMetadata::dist("std", self.target).built_by(self.compiler)) + Some(StepMetadata::dist("std", self.target).built_by(self.build_compiler)) } } @@ -1630,7 +1649,8 @@ impl Step for Extended { // the std files during uninstall. To do this ensure that rustc comes // before rust-std in the list below. tarballs.push(builder.ensure(Rustc { target_compiler })); - tarballs.push(builder.ensure(Std { compiler, target }).expect("missing std")); + tarballs + .push(builder.ensure(Std { build_compiler: compiler, target }).expect("missing std")); if target.is_windows_gnu() { tarballs.push(builder.ensure(Mingw { target }).expect("missing mingw")); diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs index 92e5084d4908b..d1c93acd78921 100644 --- a/src/bootstrap/src/core/build_steps/install.rs +++ b/src/bootstrap/src/core/build_steps/install.rs @@ -214,7 +214,7 @@ install!((self, builder, _config), // `expect` should be safe, only None when host != build, but this // only runs when host == build let tarball = builder.ensure(dist::Std { - compiler: self.compiler, + build_compiler: self.compiler, target: self.target }).expect("missing std"); install_sh(builder, "std", self.compiler.stage, Some(self.target), &tarball); diff --git a/src/bootstrap/src/utils/build_stamp.rs b/src/bootstrap/src/utils/build_stamp.rs index 6c79385190e8e..4c35388a181aa 100644 --- a/src/bootstrap/src/utils/build_stamp.rs +++ b/src/bootstrap/src/utils/build_stamp.rs @@ -136,13 +136,13 @@ pub fn codegen_backend_stamp( } /// Cargo's output path for the standard library in a given stage, compiled -/// by a particular compiler for the specified target. +/// by a particular `build_compiler` for the specified `target`. pub fn libstd_stamp( builder: &Builder<'_>, - compiler: Compiler, + build_compiler: Compiler, target: TargetSelection, ) -> BuildStamp { - BuildStamp::new(&builder.cargo_out(compiler, Mode::Std, target)).with_prefix("libstd") + BuildStamp::new(&builder.cargo_out(build_compiler, Mode::Std, target)).with_prefix("libstd") } /// Cargo's output path for librustc in a given stage, compiled by a particular From e7b7d3933254689f0b87eaf01654284169a95f10 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 12 Aug 2025 12:39:14 +0200 Subject: [PATCH 09/30] Refactor `RustcDev` dist step --- src/bootstrap/src/core/build_steps/dist.rs | 28 ++++++++++++---------- src/bootstrap/src/core/builder/tests.rs | 9 +++++++ 2 files changed, 25 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 5694688780bff..722d79439cb44 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -823,8 +823,9 @@ impl Step for Std { /// (Don't confuse this with [`RustDev`], without the `c`!) #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct RustcDev { - pub compiler: Compiler, - pub target: TargetSelection, + /// The compiler that will build rustc which will be shipped in this component. + build_compiler: Compiler, + target: TargetSelection, } impl Step for RustcDev { @@ -838,28 +839,27 @@ impl Step for RustcDev { fn make_run(run: RunConfig<'_>) { run.builder.ensure(RustcDev { - compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.host_target, - run.target, - ), + // We currently always ship a stage 2 rustc-dev component, so we build it with the + // stage 1 compiler. This might change in the future. + // The precise stage used here is important, so we hard-code it. + build_compiler: run.builder.compiler(1, run.builder.config.host_target), target: run.target, }); } fn run(self, builder: &Builder<'_>) -> Option { - let compiler = self.compiler; + let build_compiler = self.build_compiler; let target = self.target; - if skip_host_target_lib(builder, compiler) { + if skip_host_target_lib(builder, build_compiler) { return None; } - builder.ensure(compile::Rustc::new(compiler, target)); + // Build the compiler that we will ship + builder.ensure(compile::Rustc::new(build_compiler, target)); let tarball = Tarball::new(builder, "rustc-dev", &target.triple); - let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); - let stamp = build_stamp::librustc_stamp(builder, compiler_to_use, target); + let stamp = build_stamp::librustc_stamp(builder, build_compiler, target); copy_target_libs(builder, target, tarball.image_dir(), &stamp); let src_files = &["Cargo.lock"]; @@ -883,6 +883,10 @@ impl Step for RustcDev { Some(tarball.generate()) } + + fn metadata(&self) -> Option { + Some(StepMetadata::dist("rustc-dev", self.target).built_by(self.build_compiler)) + } } #[derive(Debug, Clone, Hash, PartialEq, Eq)] diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 2d4c8fb48dbf3..41fbadc56b1d9 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1134,6 +1134,7 @@ mod snapshot { [build] rustc 0 -> GenerateCopyright 1 [dist] rustc [dist] rustc 1 -> std 1 + [dist] rustc 1 -> rustc-dev 2 [dist] src <> " ); @@ -1196,6 +1197,7 @@ mod snapshot { [build] rustc 0 -> GenerateCopyright 1 [dist] rustc [dist] rustc 1 -> std 1 + [dist] rustc 1 -> rustc-dev 2 [dist] src <> [build] rustc 1 -> cargo 2 [build] rustc 1 -> rust-analyzer 2 @@ -1276,6 +1278,7 @@ mod snapshot { [dist] rustc 1 -> std 1 [build] rustc 2 -> std 2 [dist] rustc 2 -> std 2 + [dist] rustc 1 -> rustc-dev 2 [dist] src <> " ); @@ -1334,6 +1337,8 @@ mod snapshot { [build] rustdoc 2 [dist] rustc [dist] rustc 1 -> std 1 + [dist] rustc 1 -> rustc-dev 2 + [dist] rustc 1 -> rustc-dev 2 [dist] src <> " ); @@ -1413,6 +1418,8 @@ mod snapshot { [dist] rustc [dist] rustc 1 -> std 1 [dist] rustc 1 -> std 1 + [dist] rustc 1 -> rustc-dev 2 + [dist] rustc 1 -> rustc-dev 2 [dist] src <> " ); @@ -1518,6 +1525,7 @@ mod snapshot { [build] rustc 0 -> GenerateCopyright 1 [dist] rustc [dist] rustc 1 -> std 1 + [dist] rustc 1 -> rustc-dev 2 [dist] src <> [build] rustc 1 -> cargo 2 [build] rustc 1 -> rust-analyzer 2 @@ -1581,6 +1589,7 @@ mod snapshot { [dist] rustc [dist] rustc 1 -> rustc_codegen_cranelift 2 [dist] rustc 1 -> std 1 + [dist] rustc 1 -> rustc-dev 2 [dist] src <> "); } From 172c6f5067a75bb7a20c65c3da92e85ae7bd9cf5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Tue, 12 Aug 2025 12:44:29 +0200 Subject: [PATCH 10/30] Refactor `Analysis` dist step --- src/bootstrap/src/core/build_steps/dist.rs | 30 ++++++++++++---------- src/bootstrap/src/core/builder/tests.rs | 2 ++ 2 files changed, 18 insertions(+), 14 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 722d79439cb44..49262ec857d08 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -889,14 +889,19 @@ impl Step for RustcDev { } } +/// The `rust-analysis` component used to create a tarball of save-analysis metadata. +/// +/// This component has been deprecated and its contents now only include a warning about +/// its non-availability. #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Analysis { - pub compiler: Compiler, - pub target: TargetSelection, + build_compiler: Compiler, + target: TargetSelection, } impl Step for Analysis { type Output = Option; + const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -905,24 +910,17 @@ impl Step for Analysis { } fn make_run(run: RunConfig<'_>) { + // The step just produces a deprecation notice, so we just hardcode stage 1 run.builder.ensure(Analysis { - // Find the actual compiler (handling the full bootstrap option) which - // produced the save-analysis data because that data isn't copied - // through the sysroot uplifting. - compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.host_target, - run.target, - ), + build_compiler: run.builder.compiler(1, run.builder.config.host_target), target: run.target, }); } - /// Creates a tarball of (degenerate) save-analysis metadata, if available. fn run(self, builder: &Builder<'_>) -> Option { - let compiler = self.compiler; + let compiler = self.build_compiler; let target = self.target; - if !builder.config.is_host_target(compiler.host) { + if skip_host_target_lib(builder, compiler) { return None; } @@ -945,6 +943,10 @@ impl Step for Analysis { tarball.add_dir(src, format!("lib/rustlib/{}/analysis", target.triple)); Some(tarball.generate()) } + + fn metadata(&self) -> Option { + Some(StepMetadata::dist("analysis", self.target).built_by(self.build_compiler)) + } } /// Use the `builder` to make a filtered copy of `base`/X for X in (`src_dirs` - `exclude_dirs`) to @@ -1669,7 +1671,7 @@ impl Step for Extended { add_component!("llvm-components" => LlvmTools { 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!("analysis" => Analysis { build_compiler: compiler, target }); add_component!("rustc-codegen-cranelift" => CraneliftCodegenBackend { build_compiler: compiler, target diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 41fbadc56b1d9..88357a0dd56a2 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1198,6 +1198,7 @@ mod snapshot { [dist] rustc [dist] rustc 1 -> std 1 [dist] rustc 1 -> rustc-dev 2 + [dist] rustc 1 -> analysis 2 [dist] src <> [build] rustc 1 -> cargo 2 [build] rustc 1 -> rust-analyzer 2 @@ -1526,6 +1527,7 @@ mod snapshot { [dist] rustc [dist] rustc 1 -> std 1 [dist] rustc 1 -> rustc-dev 2 + [dist] rustc 1 -> analysis 2 [dist] src <> [build] rustc 1 -> cargo 2 [build] rustc 1 -> rust-analyzer 2 From 648d6ce66f76bb76ccd6b7f87560c734182c6b25 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 15 Aug 2025 19:36:29 +0200 Subject: [PATCH 11/30] Remove `compiler_for` from `dist::Cargo` --- src/bootstrap/src/core/build_steps/dist.rs | 15 ++++++++++----- src/bootstrap/src/core/builder/tests.rs | 2 ++ 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 49262ec857d08..d2308a30c47b2 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -21,7 +21,9 @@ use tracing::instrument; use crate::core::build_steps::compile::{get_codegen_backend_file, normalize_codegen_backend_name}; use crate::core::build_steps::doc::DocumentationFormat; -use crate::core::build_steps::tool::{self, RustcPrivateCompilers, Tool}; +use crate::core::build_steps::tool::{ + self, RustcPrivateCompilers, Tool, ToolTargetBuildMode, get_tool_target_compiler, +}; 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}; @@ -1293,10 +1295,9 @@ impl Step for Cargo { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Cargo { - build_compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.host_target, - run.target, + build_compiler: get_tool_target_compiler( + run.builder, + ToolTargetBuildMode::Build(run.target), ), target: run.target, }); @@ -1327,6 +1328,10 @@ impl Step for Cargo { Some(tarball.generate()) } + + fn metadata(&self) -> Option { + Some(StepMetadata::dist("cargo", self.target).built_by(self.build_compiler)) + } } #[derive(Debug, Clone, Hash, PartialEq, Eq)] diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 88357a0dd56a2..ab8eeb700eb49 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1201,6 +1201,7 @@ mod snapshot { [dist] rustc 1 -> analysis 2 [dist] src <> [build] rustc 1 -> cargo 2 + [dist] rustc 1 -> cargo 2 [build] rustc 1 -> rust-analyzer 2 [build] rustc 1 -> rustfmt 2 [build] rustc 1 -> cargo-fmt 2 @@ -1530,6 +1531,7 @@ mod snapshot { [dist] rustc 1 -> analysis 2 [dist] src <> [build] rustc 1 -> cargo 2 + [dist] rustc 1 -> cargo 2 [build] rustc 1 -> rust-analyzer 2 [build] rustc 1 -> rustfmt 2 [build] rustc 1 -> cargo-fmt 2 From fc4bf137a14fdbf90dabbf6f81cf44ab24ab331f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 15 Aug 2025 19:43:43 +0200 Subject: [PATCH 12/30] Remove `compiler_for` from `dist::RustAnalyzer` --- src/bootstrap/src/core/build_steps/dist.rs | 23 ++++++++++--------- src/bootstrap/src/core/build_steps/install.rs | 3 ++- src/bootstrap/src/core/builder/tests.rs | 2 ++ 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index d2308a30c47b2..0effc037209c3 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1334,9 +1334,10 @@ impl Step for Cargo { } } +/// Distribute the rust-analyzer component, which is used as a LSP by various IDEs. #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct RustAnalyzer { - pub build_compiler: Compiler, + pub compilers: RustcPrivateCompilers, pub target: TargetSelection, } @@ -1352,21 +1353,14 @@ impl Step for RustAnalyzer { fn make_run(run: RunConfig<'_>) { run.builder.ensure(RustAnalyzer { - build_compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.host_target, - run.target, - ), + compilers: RustcPrivateCompilers::new(run.builder, run.builder.top_stage, run.target), target: run.target, }); } fn run(self, builder: &Builder<'_>) -> Option { let target = self.target; - let compilers = - RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, self.target); - - let rust_analyzer = builder.ensure(tool::RustAnalyzer::from_compilers(compilers)); + let rust_analyzer = builder.ensure(tool::RustAnalyzer::from_compilers(self.compilers)); let mut tarball = Tarball::new(builder, "rust-analyzer", &target.triple); tarball.set_overlay(OverlayKind::RustAnalyzer); @@ -1375,6 +1369,13 @@ impl Step for RustAnalyzer { tarball.add_legal_and_readme_to("share/doc/rust-analyzer"); Some(tarball.generate()) } + + fn metadata(&self) -> Option { + Some( + StepMetadata::dist("rust-analyzer", self.target) + .built_by(self.compilers.build_compiler()), + ) + } } #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -1672,7 +1673,7 @@ impl Step for Extended { add_component!("rust-json-docs" => JsonDocs { build_compiler: target_compiler, target }); add_component!("cargo" => Cargo { build_compiler: compiler, target }); add_component!("rustfmt" => Rustfmt { build_compiler: compiler, target }); - add_component!("rust-analyzer" => RustAnalyzer { build_compiler: compiler, target }); + add_component!("rust-analyzer" => RustAnalyzer { compilers: RustcPrivateCompilers::from_build_compiler(builder, compiler, target), target }); add_component!("llvm-components" => LlvmTools { target }); add_component!("clippy" => Clippy { build_compiler: compiler, target }); add_component!("miri" => Miri { build_compiler: compiler, target }); diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs index d1c93acd78921..b155c172e356d 100644 --- a/src/bootstrap/src/core/build_steps/install.rs +++ b/src/bootstrap/src/core/build_steps/install.rs @@ -7,6 +7,7 @@ use std::path::{Component, Path, PathBuf}; use std::{env, fs}; use crate::core::build_steps::dist; +use crate::core::build_steps::tool::RustcPrivateCompilers; use crate::core::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::core::config::{Config, TargetSelection}; use crate::utils::exec::command; @@ -227,7 +228,7 @@ install!((self, builder, _config), }; RustAnalyzer, alias = "rust-analyzer", Self::should_build(_config), IS_HOST: true, { if let Some(tarball) = - builder.ensure(dist::RustAnalyzer { build_compiler: self.compiler, target: self.target }) + builder.ensure(dist::RustAnalyzer { compilers: RustcPrivateCompilers::from_build_compiler(builder, self.compiler, self.target), target: self.target }) { install_sh(builder, "rust-analyzer", self.compiler.stage, Some(self.target), &tarball); } else { diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index ab8eeb700eb49..05987b9535184 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1203,6 +1203,7 @@ mod snapshot { [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 [build] rustc 1 -> clippy-driver 2 @@ -1533,6 +1534,7 @@ mod snapshot { [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 [build] rustc 1 -> clippy-driver 2 From 5c0371072fb0b024ac3f3980c9283239ba603efb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 15 Aug 2025 20:02:32 +0200 Subject: [PATCH 13/30] Add snapshot test for `x install` --- src/bootstrap/src/core/builder/tests.rs | 66 +++++++++++++++++++++++++ src/bootstrap/src/utils/tests/mod.rs | 4 ++ 2 files changed, 70 insertions(+) diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 05987b9535184..08b1b4ac19ad9 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2265,6 +2265,72 @@ mod snapshot { .path("bootstrap") .render_steps(), @"[clippy] rustc 0 -> bootstrap 1 "); } + + #[test] + fn install_extended() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx.config("install") + .args(&[ + "--set", &format!("install.prefix={}", ctx.dir().display()), + "--set", &format!("install.sysconfdir={}", ctx.dir().display()), + "--set", "build.extended=true" + ]) + .render_steps(), @r" + [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) + [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] 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 + [doc] rustc 1 -> error-index 2 + [doc] nomicon (book) + [doc] rustc 1 -> reference (book) 2 + [doc] rustdoc (book) + [doc] rust-by-example (book) + [build] rustc 0 -> LintDocs 1 + [doc] rustc (book) + [doc] cargo (book) + [doc] clippy (book) + [doc] embedded-book (book) + [doc] edition-guide (book) + [doc] style-guide (book) + [doc] rustc 1 -> releases 2 + [build] rustc 0 -> RustInstaller 1 + [dist] docs + [build] rustc 2 -> std 2 + [dist] rustc 2 -> std 2 + [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 + [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] src <> + "); + } } struct ExecutedSteps { diff --git a/src/bootstrap/src/utils/tests/mod.rs b/src/bootstrap/src/utils/tests/mod.rs index 983680b0385c1..3332187e2a853 100644 --- a/src/bootstrap/src/utils/tests/mod.rs +++ b/src/bootstrap/src/utils/tests/mod.rs @@ -31,6 +31,10 @@ impl TestCtx { Self { directory } } + pub fn dir(&self) -> &Path { + self.directory.path() + } + /// Starts a new invocation of bootstrap that executes `kind` as its top level command /// (i.e. `x `). Returns a builder that configures the created config through CLI flags. pub fn config(&self, kind: &str) -> ConfigBuilder { From 693e2aec4e61f413a9b138cd499fd77a1544cbc4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 15 Aug 2025 21:06:37 +0200 Subject: [PATCH 14/30] Remove `compiler_for` from `dist::Clippy` --- src/bootstrap/src/core/build_steps/dist.rs | 25 ++++++++++--------- src/bootstrap/src/core/build_steps/install.rs | 2 +- src/bootstrap/src/core/builder/tests.rs | 2 ++ 3 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 0effc037209c3..f6379f7e71ea6 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1380,7 +1380,7 @@ impl Step for RustAnalyzer { #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Clippy { - pub build_compiler: Compiler, + pub compilers: RustcPrivateCompilers, pub target: TargetSelection, } @@ -1396,25 +1396,19 @@ impl Step for Clippy { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Clippy { - build_compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.host_target, - run.target, - ), + compilers: RustcPrivateCompilers::new(run.builder, run.builder.top_stage, run.target), target: run.target, }); } fn run(self, builder: &Builder<'_>) -> Option { let target = self.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::from_compilers(compilers)); - let cargoclippy = builder.ensure(tool::CargoClippy::from_compilers(compilers)); + let clippy = builder.ensure(tool::Clippy::from_compilers(self.compilers)); + let cargoclippy = builder.ensure(tool::CargoClippy::from_compilers(self.compilers)); let mut tarball = Tarball::new(builder, "clippy", &target.triple); tarball.set_overlay(OverlayKind::Clippy); @@ -1424,6 +1418,10 @@ impl Step for Clippy { tarball.add_legal_and_readme_to("share/doc/clippy"); Some(tarball.generate()) } + + fn metadata(&self) -> Option { + Some(StepMetadata::dist("clippy", self.target).built_by(self.compilers.build_compiler())) + } } #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -1668,14 +1666,17 @@ impl Step for Extended { tarballs.push(builder.ensure(Mingw { target }).expect("missing mingw")); } + let rustc_private_compilers = + RustcPrivateCompilers::from_build_compiler(builder, compiler, target); + add_component!("rust-docs" => Docs { host: target }); // Std stage N is documented with compiler stage N add_component!("rust-json-docs" => JsonDocs { build_compiler: target_compiler, target }); add_component!("cargo" => Cargo { build_compiler: compiler, target }); add_component!("rustfmt" => Rustfmt { build_compiler: compiler, target }); - add_component!("rust-analyzer" => RustAnalyzer { compilers: RustcPrivateCompilers::from_build_compiler(builder, compiler, target), target }); + add_component!("rust-analyzer" => RustAnalyzer { compilers: rustc_private_compilers, target }); add_component!("llvm-components" => LlvmTools { target }); - add_component!("clippy" => Clippy { build_compiler: compiler, target }); + add_component!("clippy" => Clippy { compilers: rustc_private_compilers, target }); add_component!("miri" => Miri { build_compiler: compiler, target }); add_component!("analysis" => Analysis { build_compiler: compiler, target }); add_component!("rustc-codegen-cranelift" => CraneliftCodegenBackend { diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs index b155c172e356d..aea54512f7c48 100644 --- a/src/bootstrap/src/core/build_steps/install.rs +++ b/src/bootstrap/src/core/build_steps/install.rs @@ -239,7 +239,7 @@ install!((self, builder, _config), }; Clippy, alias = "clippy", Self::should_build(_config), IS_HOST: true, { let tarball = builder - .ensure(dist::Clippy { build_compiler: self.compiler, target: self.target }) + .ensure(dist::Clippy { compilers: RustcPrivateCompilers::from_build_compiler(builder, self.compiler, self.target), target: self.target }) .expect("missing clippy"); install_sh(builder, "clippy", self.compiler.stage, Some(self.target), &tarball); }; diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 08b1b4ac19ad9..2a922d5f4b8ca 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1208,6 +1208,7 @@ mod snapshot { [build] rustc 1 -> cargo-fmt 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 "); @@ -1539,6 +1540,7 @@ mod snapshot { [build] rustc 1 -> cargo-fmt 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 [build] rustc 1 -> LlvmBitcodeLinker 2 From 1f7f7f55a8b63f36d0ca91b46f2a4e0bcb606b8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 15 Aug 2025 20:11:45 +0200 Subject: [PATCH 15/30] Remove `compiler_for` from `dist::Miri` --- src/bootstrap/src/core/build_steps/dist.rs | 20 +++++++++---------- src/bootstrap/src/core/build_steps/install.rs | 2 +- src/bootstrap/src/core/builder/tests.rs | 3 +++ 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index f6379f7e71ea6..f3276ebf7311b 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1426,7 +1426,7 @@ impl Step for Clippy { #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Miri { - pub build_compiler: Compiler, + pub compilers: RustcPrivateCompilers, pub target: TargetSelection, } @@ -1442,11 +1442,7 @@ impl Step for Miri { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Miri { - build_compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.host_target, - run.target, - ), + compilers: RustcPrivateCompilers::new(run.builder, run.builder.top_stage, run.target), target: run.target, }); } @@ -1459,10 +1455,8 @@ impl Step for Miri { return None; } - 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 miri = builder.ensure(tool::Miri::from_compilers(self.compilers)); + let cargomiri = builder.ensure(tool::CargoMiri::from_compilers(self.compilers)); let mut tarball = Tarball::new(builder, "miri", &self.target.triple); tarball.set_overlay(OverlayKind::Miri); @@ -1472,6 +1466,10 @@ impl Step for Miri { tarball.add_legal_and_readme_to("share/doc/miri"); Some(tarball.generate()) } + + fn metadata(&self) -> Option { + Some(StepMetadata::dist("miri", self.target).built_by(self.compilers.build_compiler())) + } } #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -1677,7 +1675,7 @@ impl Step for Extended { add_component!("rust-analyzer" => RustAnalyzer { compilers: rustc_private_compilers, target }); add_component!("llvm-components" => LlvmTools { target }); add_component!("clippy" => Clippy { compilers: rustc_private_compilers, target }); - add_component!("miri" => Miri { build_compiler: compiler, target }); + add_component!("miri" => Miri { compilers: rustc_private_compilers, target }); add_component!("analysis" => Analysis { build_compiler: compiler, target }); add_component!("rustc-codegen-cranelift" => CraneliftCodegenBackend { build_compiler: compiler, diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs index aea54512f7c48..da3eef74b2b97 100644 --- a/src/bootstrap/src/core/build_steps/install.rs +++ b/src/bootstrap/src/core/build_steps/install.rs @@ -244,7 +244,7 @@ install!((self, builder, _config), install_sh(builder, "clippy", self.compiler.stage, Some(self.target), &tarball); }; Miri, alias = "miri", Self::should_build(_config), IS_HOST: true, { - if let Some(tarball) = builder.ensure(dist::Miri { build_compiler: self.compiler, target: self.target }) { + 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); } else { // Miri is only available on nightly diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 2a922d5f4b8ca..1646c4bd63143 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1211,6 +1211,7 @@ mod snapshot { [dist] rustc 1 -> clippy 2 [build] rustc 1 -> miri 2 [build] rustc 1 -> cargo-miri 2 + [dist] rustc 1 -> miri 2 "); } @@ -1543,6 +1544,7 @@ mod snapshot { [dist] rustc 1 -> clippy 2 [build] rustc 1 -> miri 2 [build] rustc 1 -> cargo-miri 2 + [dist] rustc 1 -> miri 2 [build] rustc 1 -> LlvmBitcodeLinker 2 [doc] rustc 2 -> std 2 crates=[] "); @@ -2330,6 +2332,7 @@ mod snapshot { [dist] rustc 2 -> clippy 3 [build] rustc 2 -> miri 3 [build] rustc 2 -> cargo-miri 3 + [dist] rustc 2 -> miri 3 [dist] src <> "); } From dfc66f08b91b7520e9b7b25b65051d948ab08197 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 15 Aug 2025 20:14:57 +0200 Subject: [PATCH 16/30] Remove `compiler_for` from `dist::CraneliftCodegenBackend` --- src/bootstrap/src/core/build_steps/dist.rs | 17 ++++++----------- src/bootstrap/src/core/build_steps/install.rs | 2 +- 2 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index f3276ebf7311b..8915c2fe56df5 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1474,7 +1474,7 @@ impl Step for Miri { #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct CraneliftCodegenBackend { - pub build_compiler: Compiler, + pub compilers: RustcPrivateCompilers, pub target: TargetSelection, } @@ -1498,11 +1498,7 @@ impl Step for CraneliftCodegenBackend { fn make_run(run: RunConfig<'_>) { run.builder.ensure(CraneliftCodegenBackend { - build_compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.host_target, - run.target, - ), + compilers: RustcPrivateCompilers::new(run.builder, run.builder.top_stage, run.target), target: run.target, }); } @@ -1516,8 +1512,6 @@ impl Step for CraneliftCodegenBackend { } let target = self.target; - let compilers = - RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, target); if !target_supports_cranelift_backend(target) { builder.info("target not supported by rustc_codegen_cranelift. skipping"); return None; @@ -1528,6 +1522,7 @@ impl Step for CraneliftCodegenBackend { tarball.is_preview(true); tarball.add_legal_and_readme_to("share/doc/rustc_codegen_cranelift"); + let compilers = self.compilers; let stamp = builder.ensure(compile::CraneliftCodegenBackend { compilers }); if builder.config.dry_run() { @@ -1557,8 +1552,8 @@ impl Step for CraneliftCodegenBackend { fn metadata(&self) -> Option { Some( - StepMetadata::dist("rustc_codegen_cranelift", self.build_compiler.host) - .built_by(self.build_compiler), + StepMetadata::dist("rustc_codegen_cranelift", self.target) + .built_by(self.compilers.build_compiler()), ) } } @@ -1678,7 +1673,7 @@ impl Step for Extended { add_component!("miri" => Miri { compilers: rustc_private_compilers, target }); add_component!("analysis" => Analysis { build_compiler: compiler, target }); add_component!("rustc-codegen-cranelift" => CraneliftCodegenBackend { - build_compiler: compiler, + compilers: rustc_private_compilers, target }); add_component!("llvm-bitcode-linker" => LlvmBitcodeLinker { diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs index da3eef74b2b97..07a8ee9957560 100644 --- a/src/bootstrap/src/core/build_steps/install.rs +++ b/src/bootstrap/src/core/build_steps/install.rs @@ -282,7 +282,7 @@ install!((self, builder, _config), }; RustcCodegenCranelift, alias = "rustc-codegen-cranelift", Self::should_build(_config), IS_HOST: true, { if let Some(tarball) = builder.ensure(dist::CraneliftCodegenBackend { - build_compiler: self.compiler, + compilers: RustcPrivateCompilers::new(builder, builder.top_stage, self.target), target: self.target }) { install_sh(builder, "rustc-codegen-cranelift", self.compiler.stage, Some(self.target), &tarball); From 887831fb7f4aee76e742444eeca2b6665aefe1d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 15 Aug 2025 20:18:04 +0200 Subject: [PATCH 17/30] Remove `compiler_for` from `dist::Rustfmt` --- src/bootstrap/src/core/build_steps/dist.rs | 21 ++++++++----------- src/bootstrap/src/core/build_steps/install.rs | 2 +- src/bootstrap/src/core/builder/tests.rs | 3 +++ 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 8915c2fe56df5..0c8a03cbbef85 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1560,7 +1560,7 @@ impl Step for CraneliftCodegenBackend { #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Rustfmt { - pub build_compiler: Compiler, + pub compilers: RustcPrivateCompilers, pub target: TargetSelection, } @@ -1576,21 +1576,14 @@ impl Step for Rustfmt { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Rustfmt { - build_compiler: run.builder.compiler_for( - run.builder.top_stage, - run.builder.config.host_target, - run.target, - ), + compilers: RustcPrivateCompilers::new(run.builder, run.builder.top_stage, run.target), target: run.target, }); } fn run(self, builder: &Builder<'_>) -> Option { - let compilers = - RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, self.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::from_compilers(self.compilers)); + let cargofmt = builder.ensure(tool::Cargofmt::from_compilers(self.compilers)); let mut tarball = Tarball::new(builder, "rustfmt", &self.target.triple); tarball.set_overlay(OverlayKind::Rustfmt); @@ -1600,6 +1593,10 @@ impl Step for Rustfmt { tarball.add_legal_and_readme_to("share/doc/rustfmt"); Some(tarball.generate()) } + + fn metadata(&self) -> Option { + Some(StepMetadata::dist("rustfmt", self.target).built_by(self.compilers.build_compiler())) + } } #[derive(Debug, Clone, Hash, PartialEq, Eq)] @@ -1666,7 +1663,7 @@ impl Step for Extended { // Std stage N is documented with compiler stage N add_component!("rust-json-docs" => JsonDocs { build_compiler: target_compiler, target }); add_component!("cargo" => Cargo { build_compiler: compiler, target }); - add_component!("rustfmt" => Rustfmt { build_compiler: compiler, target }); + add_component!("rustfmt" => Rustfmt { compilers: rustc_private_compilers, target }); add_component!("rust-analyzer" => RustAnalyzer { compilers: rustc_private_compilers, target }); add_component!("llvm-components" => LlvmTools { target }); add_component!("clippy" => Clippy { compilers: rustc_private_compilers, target }); diff --git a/src/bootstrap/src/core/build_steps/install.rs b/src/bootstrap/src/core/build_steps/install.rs index 07a8ee9957560..ee8f864d2c2e8 100644 --- a/src/bootstrap/src/core/build_steps/install.rs +++ b/src/bootstrap/src/core/build_steps/install.rs @@ -264,7 +264,7 @@ install!((self, builder, _config), }; Rustfmt, alias = "rustfmt", Self::should_build(_config), IS_HOST: true, { if let Some(tarball) = builder.ensure(dist::Rustfmt { - build_compiler: self.compiler, + compilers: RustcPrivateCompilers::from_build_compiler(builder, self.compiler, self.target), target: self.target }) { install_sh(builder, "rustfmt", self.compiler.stage, Some(self.target), &tarball); diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 1646c4bd63143..67ad0cf789723 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1206,6 +1206,7 @@ mod snapshot { [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 @@ -1539,6 +1540,7 @@ mod snapshot { [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 @@ -2327,6 +2329,7 @@ mod snapshot { [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 From e68c93b538126c4ebd7b561fab9924779b84320a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 15 Aug 2025 20:23:42 +0200 Subject: [PATCH 18/30] Remove `compiler_for` from `dist::Extended` --- src/bootstrap/src/core/build_steps/dist.rs | 36 ++++++++++++---------- src/bootstrap/src/core/builder/tests.rs | 2 ++ 2 files changed, 21 insertions(+), 17 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 0c8a03cbbef85..e06566742f950 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -1599,10 +1599,10 @@ impl Step for Rustfmt { } } +/// Extended archive that contains the compiler, standard library and a bunch of tools. #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct Extended { - stage: u32, - host: TargetSelection, + build_compiler: Compiler, target: TargetSelection, } @@ -1618,8 +1618,9 @@ impl Step for Extended { fn make_run(run: RunConfig<'_>) { run.builder.ensure(Extended { - stage: run.builder.top_stage, - host: run.builder.config.host_target, + build_compiler: run + .builder + .compiler(run.builder.top_stage - 1, run.builder.host_target), target: run.target, }); } @@ -1627,10 +1628,7 @@ impl Step for Extended { /// Creates a combined installer for the specified target in the provided stage. fn run(self, builder: &Builder<'_>) { let target = self.target; - let stage = self.stage; - let compiler = builder.compiler_for(self.stage, self.host, self.target); - - builder.info(&format!("Dist extended stage{} ({})", compiler.stage, target)); + builder.info(&format!("Dist extended stage{} ({target})", builder.top_stage)); let mut tarballs = Vec::new(); let mut built_tools = HashSet::new(); @@ -1643,38 +1641,38 @@ impl Step for Extended { }; } - let target_compiler = builder.compiler(stage, target); + let rustc_private_compilers = + RustcPrivateCompilers::from_build_compiler(builder, self.build_compiler, target); + let build_compiler = rustc_private_compilers.build_compiler(); + let target_compiler = rustc_private_compilers.target_compiler(); + // When rust-std package split from rustc, we needed to ensure that during // upgrades rustc was upgraded before rust-std. To avoid rustc clobbering // the std files during uninstall. To do this ensure that rustc comes // before rust-std in the list below. tarballs.push(builder.ensure(Rustc { target_compiler })); - tarballs - .push(builder.ensure(Std { build_compiler: compiler, target }).expect("missing std")); + tarballs.push(builder.ensure(Std { build_compiler, target }).expect("missing std")); if target.is_windows_gnu() { tarballs.push(builder.ensure(Mingw { target }).expect("missing mingw")); } - let rustc_private_compilers = - RustcPrivateCompilers::from_build_compiler(builder, compiler, target); - add_component!("rust-docs" => Docs { host: target }); // Std stage N is documented with compiler stage N add_component!("rust-json-docs" => JsonDocs { build_compiler: target_compiler, target }); - add_component!("cargo" => Cargo { build_compiler: compiler, target }); + add_component!("cargo" => Cargo { build_compiler, target }); add_component!("rustfmt" => Rustfmt { compilers: rustc_private_compilers, target }); add_component!("rust-analyzer" => RustAnalyzer { compilers: rustc_private_compilers, target }); add_component!("llvm-components" => LlvmTools { target }); add_component!("clippy" => Clippy { compilers: rustc_private_compilers, target }); add_component!("miri" => Miri { compilers: rustc_private_compilers, target }); - add_component!("analysis" => Analysis { build_compiler: compiler, target }); + add_component!("analysis" => Analysis { build_compiler, target }); add_component!("rustc-codegen-cranelift" => CraneliftCodegenBackend { compilers: rustc_private_compilers, target }); add_component!("llvm-bitcode-linker" => LlvmBitcodeLinker { - build_compiler: compiler, + build_compiler, target }); @@ -2140,6 +2138,10 @@ impl Step for Extended { } } } + + fn metadata(&self) -> Option { + Some(StepMetadata::dist("extended", self.target).built_by(self.build_compiler)) + } } fn add_env( diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 67ad0cf789723..dd52b6cef68ef 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1213,6 +1213,7 @@ mod snapshot { [build] rustc 1 -> miri 2 [build] rustc 1 -> cargo-miri 2 [dist] rustc 1 -> miri 2 + [dist] rustc 1 -> extended 2 "); } @@ -1549,6 +1550,7 @@ mod snapshot { [dist] rustc 1 -> miri 2 [build] rustc 1 -> LlvmBitcodeLinker 2 [doc] rustc 2 -> std 2 crates=[] + [dist] rustc 1 -> extended 2 "); } From 699e5fe933a73a538a163d813f5e34bba224912d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 15 Aug 2025 20:27:11 +0200 Subject: [PATCH 19/30] Cleanup `dist::Bootstrap` and add a simple test for it --- src/bootstrap/src/core/build_steps/dist.rs | 10 ++++++++-- src/bootstrap/src/core/builder/tests.rs | 13 +++++++++++++ 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index e06566742f950..55df2ea076fcf 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -2604,15 +2604,17 @@ impl Step for RustDev { /// Tarball intended for internal consumption to ease rustc/std development. /// +/// It only packages the binaries that were already compiled when bootstrap itself was built. +/// /// Should not be considered stable by end users. #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct Bootstrap { - pub target: TargetSelection, + target: TargetSelection, } impl Step for Bootstrap { type Output = Option; - const DEFAULT: bool = false; + const IS_HOST: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -2639,6 +2641,10 @@ impl Step for Bootstrap { Some(tarball.generate()) } + + fn metadata(&self) -> Option { + Some(StepMetadata::dist("bootstrap", self.target)) + } } /// Tarball containing a prebuilt version of the build-manifest tool, intended to be used by the diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index dd52b6cef68ef..e8ac73d57ff75 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1608,6 +1608,19 @@ mod snapshot { "); } + #[test] + fn dist_bootstrap() { + let ctx = TestCtx::new(); + insta::assert_snapshot!( + ctx + .config("dist") + .path("bootstrap") + .render_steps(), @r" + [build] rustc 0 -> RustInstaller 1 + [dist] bootstrap + "); + } + #[test] fn check_compiler_no_explicit_stage() { let ctx = TestCtx::new(); From e8af2365c097d358c5c672688c30d04832dede46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 15 Aug 2025 20:31:13 +0200 Subject: [PATCH 20/30] Cleanup the last few dist steps --- src/bootstrap/src/core/build_steps/dist.rs | 22 +++++++++++++++++----- src/bootstrap/src/core/builder/tests.rs | 9 +++++++++ 2 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 55df2ea076fcf..7689a155bd1f2 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -2653,12 +2653,12 @@ impl Step for Bootstrap { /// Should not be considered stable by end users. #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct BuildManifest { - pub target: TargetSelection, + target: TargetSelection, } impl Step for BuildManifest { type Output = GeneratedTarball; - const DEFAULT: bool = false; + const IS_HOST: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -2676,16 +2676,20 @@ impl Step for BuildManifest { tarball.add_file(&build_manifest, "bin", FileType::Executable); tarball.generate() } + + fn metadata(&self) -> Option { + Some(StepMetadata::dist("build-manifest", self.target)) + } } /// Tarball containing artifacts necessary to reproduce the build of rustc. /// -/// Currently this is the PGO profile data. +/// Currently this is the PGO (and possibly BOLT) profile data. /// /// Should not be considered stable by end users. #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct ReproducibleArtifacts { - pub target: TargetSelection, + target: TargetSelection, } impl Step for ReproducibleArtifacts { @@ -2718,6 +2722,10 @@ impl Step for ReproducibleArtifacts { } if added_anything { Some(tarball.generate()) } else { None } } + + fn metadata(&self) -> Option { + Some(StepMetadata::dist("reproducible-artifacts", self.target)) + } } /// Tarball containing a prebuilt version of the libgccjit library, @@ -2725,7 +2733,7 @@ impl Step for ReproducibleArtifacts { /// backend needing a prebuilt libLLVM). #[derive(Clone, Debug, Eq, Hash, PartialEq)] pub struct Gcc { - pub target: TargetSelection, + target: TargetSelection, } impl Step for Gcc { @@ -2745,4 +2753,8 @@ impl Step for Gcc { tarball.add_file(&output.libgccjit, "lib", FileType::NativeLibrary); tarball.generate() } + + fn metadata(&self) -> Option { + Some(StepMetadata::dist("gcc", self.target)) + } } diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index e8ac73d57ff75..18c23c5f689c8 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1136,6 +1136,7 @@ mod snapshot { [dist] rustc 1 -> std 1 [dist] rustc 1 -> rustc-dev 2 [dist] src <> + [dist] reproducible-artifacts " ); } @@ -1214,6 +1215,7 @@ mod snapshot { [build] rustc 1 -> cargo-miri 2 [dist] rustc 1 -> miri 2 [dist] rustc 1 -> extended 2 + [dist] reproducible-artifacts "); } @@ -1287,6 +1289,7 @@ mod snapshot { [dist] rustc 2 -> std 2 [dist] rustc 1 -> rustc-dev 2 [dist] src <> + [dist] reproducible-artifacts " ); } @@ -1347,6 +1350,8 @@ mod snapshot { [dist] rustc 1 -> rustc-dev 2 [dist] rustc 1 -> rustc-dev 2 [dist] src <> + [dist] reproducible-artifacts + [dist] reproducible-artifacts " ); } @@ -1428,6 +1433,8 @@ mod snapshot { [dist] rustc 1 -> rustc-dev 2 [dist] rustc 1 -> rustc-dev 2 [dist] src <> + [dist] reproducible-artifacts + [dist] reproducible-artifacts " ); } @@ -1551,6 +1558,7 @@ mod snapshot { [build] rustc 1 -> LlvmBitcodeLinker 2 [doc] rustc 2 -> std 2 crates=[] [dist] rustc 1 -> extended 2 + [dist] reproducible-artifacts "); } @@ -1605,6 +1613,7 @@ mod snapshot { [dist] rustc 1 -> std 1 [dist] rustc 1 -> rustc-dev 2 [dist] src <> + [dist] reproducible-artifacts "); } From 2074e1344d33884324d125271d34e35b2d503ab0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 15 Aug 2025 20:33:29 +0200 Subject: [PATCH 21/30] Forbid running install steps on stage 0 --- src/bootstrap/src/core/config/config.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 485960f425664..7f7d2b3c0340c 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1045,6 +1045,10 @@ impl Config { eprintln!("ERROR: cannot dist anything on stage 0. Use at least stage 1."); exit!(1); } + (0, Subcommand::Install { .. }) => { + eprintln!("ERROR: cannot install anything on stage 0. Use at least stage 1."); + exit!(1); + } _ => {} } 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 22/30] Fix staging in `x install` --- src/bootstrap/src/core/build_steps/dist.rs | 37 ++++---- src/bootstrap/src/core/build_steps/install.rs | 84 +++++++++---------- src/bootstrap/src/core/builder/tests.rs | 37 ++++---- 3 files changed, 77 insertions(+), 81 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 7689a155bd1f2..f5829f89e1d7c 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -762,36 +762,39 @@ pub struct Std { pub target: TargetSelection, } -impl Step for Std { - type Output = Option; - const DEFAULT: bool = true; - - fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { - run.alias("rust-std") - } - - fn make_run(run: RunConfig<'_>) { +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 = run.builder.top_stage; + let top_stage = builder.top_stage; let stage = if top_stage > 1 - && compile::Std::should_be_uplifted_from_stage_1(run.builder, top_stage, run.target) + && compile::Std::should_be_uplifted_from_stage_1(builder, top_stage, target) { - run.builder.info(&format!( + 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 + target )); 1 } else { top_stage }; - run.builder.ensure(Std { - build_compiler: run.builder.compiler(stage, run.builder.config.host_target), - target: run.target, - }); + Std { build_compiler: builder.compiler(stage, builder.config.host_target), target } + } +} + +impl Step for Std { + type Output = Option; + const DEFAULT: bool = true; + + fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { + run.alias("rust-std") + } + + fn make_run(run: RunConfig<'_>) { + 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 ee8f864d2c2e8..ce68dbf5a2010 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 18c23c5f689c8..1471b5df84637 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 <> "); } From 0579f055cd518904523758caec98df0273d2854e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 16 Aug 2025 08:55:53 +0200 Subject: [PATCH 23/30] Add change tracker entry --- src/bootstrap/src/core/config/config.rs | 4 ++-- src/bootstrap/src/utils/change_tracker.rs | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/config/config.rs b/src/bootstrap/src/core/config/config.rs index 7f7d2b3c0340c..9ac8143439a23 100644 --- a/src/bootstrap/src/core/config/config.rs +++ b/src/bootstrap/src/core/config/config.rs @@ -1041,11 +1041,11 @@ impl Config { eprintln!("ERROR: cannot run clippy on stage 0. Use at least stage 1."); exit!(1); } - (0, Subcommand::Dist { .. }) => { + (0, Subcommand::Dist) => { eprintln!("ERROR: cannot dist anything on stage 0. Use at least stage 1."); exit!(1); } - (0, Subcommand::Install { .. }) => { + (0, Subcommand::Install) => { eprintln!("ERROR: cannot install anything on stage 0. Use at least stage 1."); exit!(1); } diff --git a/src/bootstrap/src/utils/change_tracker.rs b/src/bootstrap/src/utils/change_tracker.rs index 4fb5891ed181a..54f563fe68c70 100644 --- a/src/bootstrap/src/utils/change_tracker.rs +++ b/src/bootstrap/src/utils/change_tracker.rs @@ -516,4 +516,9 @@ pub const CONFIG_CHANGE_HISTORY: &[ChangeInfo] = &[ severity: ChangeSeverity::Info, summary: "Build/check now supports forwarding `--timings` flag to cargo.", }, + ChangeInfo { + change_id: 145472, + severity: ChangeSeverity::Warning, + summary: "It is no longer possible to `x dist` or `x install` with stage 0. All dist and install commands have to be on stage 1+.", + }, ]; From ba1bc643250ee4eeae57a2182b82f3f9b27955c4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 16 Aug 2025 09:57:16 +0200 Subject: [PATCH 24/30] Fix doc link --- src/bootstrap/src/core/build_steps/dist.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index f5829f89e1d7c..158e514df5ea5 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -142,7 +142,7 @@ impl Step for JsonDocs { /// various in-tree helper tools (bootstrap, build_helper, tidy), /// and also rustc_private tools like rustdoc, clippy, miri or rustfmt. /// -/// It is currently hosted at https://doc.rust-lang.org/nightly/nightly-rustc +/// It is currently hosted at . #[derive(Debug, Clone, Hash, PartialEq, Eq)] pub struct RustcDocs { target: TargetSelection, From 3303770847da3f2364c3e1851e6b029697c27efe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 20 Aug 2025 15:16:18 +0200 Subject: [PATCH 25/30] Don't try to cross-document bootstrap tools --- src/bootstrap/src/core/build_steps/doc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index 7fe19c00ef5fa..e0cea046c59a7 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -994,7 +994,7 @@ macro_rules! tool_doc { (compilers.build_compiler(), Mode::ToolRustc) } else { // bootstrap/host tools have to be documented with the stage 0 compiler - (prepare_doc_compiler(run.builder, target, 1), Mode::ToolBootstrap) + (prepare_doc_compiler(run.builder, run.builder.host_target, 1), Mode::ToolBootstrap) }; run.builder.ensure($tool { build_compiler, mode, target }); From 0470945ec8bcd1b3e5589ed979c30572ee65b30a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Wed, 20 Aug 2025 15:17:25 +0200 Subject: [PATCH 26/30] Remove the `x dist rust-std` built optimization special-case --- src/bootstrap/src/core/build_steps/dist.rs | 22 +++------------- src/bootstrap/src/core/builder/tests.rs | 29 +++++++++++++++------- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 158e514df5ea5..299ed8442aec7 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -764,24 +764,10 @@ pub struct Std { 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 } + Std { + build_compiler: builder.compiler(builder.top_stage, builder.config.host_target), + target, + } } } diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 1471b5df84637..64e60636bac32 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -1133,7 +1133,8 @@ mod snapshot { [dist] mingw [build] rustc 0 -> GenerateCopyright 1 [dist] rustc - [dist] rustc 1 -> std 1 + [build] rustc 2 -> std 2 + [dist] rustc 2 -> std 2 [dist] rustc 1 -> rustc-dev 2 [dist] src <> [dist] reproducible-artifacts @@ -1197,7 +1198,8 @@ mod snapshot { [build] rustc 1 -> rust-analyzer-proc-macro-srv 2 [build] rustc 0 -> GenerateCopyright 1 [dist] rustc - [dist] rustc 1 -> std 1 + [build] rustc 2 -> std 2 + [dist] rustc 2 -> std 2 [dist] rustc 1 -> rustc-dev 2 [dist] rustc 1 -> analysis 2 [dist] src <> @@ -1214,6 +1216,7 @@ mod snapshot { [build] rustc 1 -> miri 2 [build] rustc 1 -> cargo-miri 2 [dist] rustc 1 -> miri 2 + [dist] rustc 1 -> std 1 [dist] rustc 1 -> extended 2 [dist] reproducible-artifacts "); @@ -1284,7 +1287,8 @@ mod snapshot { [dist] mingw [build] rustc 0 -> GenerateCopyright 1 [dist] rustc - [dist] rustc 1 -> std 1 + [build] rustc 2 -> std 2 + [dist] rustc 2 -> std 2 [build] rustc 2 -> std 2 [dist] rustc 2 -> std 2 [dist] rustc 1 -> rustc-dev 2 @@ -1346,7 +1350,8 @@ mod snapshot { [dist] rustc [build] rustdoc 2 [dist] rustc - [dist] rustc 1 -> std 1 + [build] rustc 2 -> std 2 + [dist] rustc 2 -> std 2 [dist] rustc 1 -> rustc-dev 2 [dist] rustc 1 -> rustc-dev 2 [dist] src <> @@ -1428,8 +1433,10 @@ mod snapshot { [dist] rustc [build] rustdoc 2 [dist] rustc - [dist] rustc 1 -> std 1 - [dist] rustc 1 -> std 1 + [build] rustc 2 -> std 2 + [dist] rustc 2 -> std 2 + [build] rustc 2 -> std 2 + [dist] rustc 2 -> std 2 [dist] rustc 1 -> rustc-dev 2 [dist] rustc 1 -> rustc-dev 2 [dist] src <> @@ -1538,7 +1545,8 @@ mod snapshot { [build] rustc 1 -> rust-analyzer-proc-macro-srv 2 [build] rustc 0 -> GenerateCopyright 1 [dist] rustc - [dist] rustc 1 -> std 1 + [build] rustc 2 -> std 2 + [dist] rustc 2 -> std 2 [dist] rustc 1 -> rustc-dev 2 [dist] rustc 1 -> analysis 2 [dist] src <> @@ -1556,6 +1564,7 @@ mod snapshot { [build] rustc 1 -> cargo-miri 2 [dist] rustc 1 -> miri 2 [build] rustc 1 -> LlvmBitcodeLinker 2 + [dist] rustc 1 -> std 1 [doc] rustc 2 -> std 2 crates=[] [dist] rustc 1 -> extended 2 [dist] reproducible-artifacts @@ -1610,7 +1619,8 @@ mod snapshot { [build] rustc 0 -> GenerateCopyright 1 [dist] rustc [dist] rustc 1 -> rustc_codegen_cranelift 2 - [dist] rustc 1 -> std 1 + [build] rustc 2 -> std 2 + [dist] rustc 2 -> std 2 [dist] rustc 1 -> rustc-dev 2 [dist] src <> [dist] reproducible-artifacts @@ -2340,7 +2350,8 @@ mod snapshot { [doc] rustc 1 -> releases 2 [build] rustc 0 -> RustInstaller 1 [dist] docs - [dist] rustc 1 -> std 1 + [build] rustc 2 -> std 2 + [dist] rustc 2 -> std 2 [build] rustc 1 -> rust-analyzer-proc-macro-srv 2 [build] rustc 0 -> GenerateCopyright 1 [dist] rustc From 21c30eac49307a67b1ff81564bb94590926e10c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Fri, 22 Aug 2025 21:50:31 +0200 Subject: [PATCH 27/30] Fix install test on Windows --- src/bootstrap/src/core/builder/tests.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/src/core/builder/tests.rs b/src/bootstrap/src/core/builder/tests.rs index 64e60636bac32..5260b43f706cd 100644 --- a/src/bootstrap/src/core/builder/tests.rs +++ b/src/bootstrap/src/core/builder/tests.rs @@ -2312,8 +2312,9 @@ mod snapshot { insta::assert_snapshot!( ctx.config("install") .args(&[ - "--set", &format!("install.prefix={}", ctx.dir().display()), - "--set", &format!("install.sysconfdir={}", ctx.dir().display()), + // Using backslashes fails with `--set` + "--set", &format!("install.prefix={}", ctx.dir().display()).replace("\\", "/"), + "--set", &format!("install.sysconfdir={}", ctx.dir().display()).replace("\\", "/"), "--set", "build.extended=true" ]) .render_steps(), @r" From a62488bb27834cc3e7ef8bb06d6fcdeec7e932c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 23 Aug 2025 11:17:35 +0200 Subject: [PATCH 28/30] Handle uplifting in libstd dist step --- src/bootstrap/src/core/build_steps/compile.rs | 21 ++++++++++++------- src/bootstrap/src/core/build_steps/dist.rs | 6 ++++-- src/bootstrap/src/core/builder/mod.rs | 8 +++++-- 3 files changed, 23 insertions(+), 12 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index 7b3e5db58f807..8cad5b920b913 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -123,7 +123,9 @@ impl Std { } impl Step for Std { - type Output = (); + /// Build stamp of std, if it was indeed built or uplifted. + type Output = Option; + const DEFAULT: bool = true; fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> { @@ -160,7 +162,7 @@ impl Step for Std { /// This will build the standard library for a particular stage of the build /// using the `compiler` targeting the `target` architecture. The artifacts /// created will also be linked into the sysroot directory. - fn run(self, builder: &Builder<'_>) { + fn run(self, builder: &Builder<'_>) -> Self::Output { let target = self.target; // We already have std ready to be used for stage 0. @@ -168,7 +170,7 @@ impl Step for Std { let compiler = self.build_compiler; builder.ensure(StdLink::from_std(self, compiler)); - return; + return None; } let build_compiler = if builder.download_rustc() && self.force_recompile { @@ -193,7 +195,7 @@ impl Step for Std { &sysroot, builder.config.ci_rust_std_contents(), ); - return; + return None; } if builder.config.keep_stage.contains(&build_compiler.stage) @@ -209,7 +211,7 @@ impl Step for Std { self.copy_extra_objects(builder, &build_compiler, target); builder.ensure(StdLink::from_std(self, build_compiler)); - return; + return Some(build_stamp::libstd_stamp(builder, build_compiler, target)); } let mut target_deps = builder.ensure(StartupObjects { compiler: build_compiler, target }); @@ -219,7 +221,7 @@ impl Step for Std { if Self::should_be_uplifted_from_stage_1(builder, build_compiler.stage, target) { let build_compiler_for_std_to_uplift = builder.compiler(1, builder.host_target); - builder.std(build_compiler_for_std_to_uplift, target); + let stage_1_stamp = builder.std(build_compiler_for_std_to_uplift, target); let msg = if build_compiler_for_std_to_uplift.host == target { format!( @@ -240,7 +242,7 @@ impl Step for Std { self.copy_extra_objects(builder, &build_compiler, target); builder.ensure(StdLink::from_std(self, build_compiler_for_std_to_uplift)); - return; + return stage_1_stamp; } target_deps.extend(self.copy_extra_objects(builder, &build_compiler, target)); @@ -293,11 +295,13 @@ impl Step for Std { build_compiler, target, ); + + let stamp = build_stamp::libstd_stamp(builder, build_compiler, target); run_cargo( builder, cargo, vec![], - &build_stamp::libstd_stamp(builder, build_compiler, target), + &stamp, target_deps, self.is_for_mir_opt_tests, // is_check false, @@ -307,6 +311,7 @@ impl Step for Std { self, builder.compiler(build_compiler.stage, builder.config.host_target), )); + Some(stamp) } fn metadata(&self) -> Option { diff --git a/src/bootstrap/src/core/build_steps/dist.rs b/src/bootstrap/src/core/build_steps/dist.rs index 299ed8442aec7..3c322256cf277 100644 --- a/src/bootstrap/src/core/build_steps/dist.rs +++ b/src/bootstrap/src/core/build_steps/dist.rs @@ -791,12 +791,14 @@ impl Step for Std { return None; } - builder.std(build_compiler, target); + // It's possible that std was uplifted and thus built with a different build compiler + // So we need to read the stamp that was actually generated when std was built + let stamp = + builder.std(build_compiler, target).expect("Standard library has to be built for dist"); let mut tarball = Tarball::new(builder, "rust-std", &target.triple); tarball.include_target_in_component_name(true); - let stamp = build_stamp::libstd_stamp(builder, build_compiler, target); verify_uefi_rlib_format(builder, target, &stamp); copy_target_libs(builder, target, tarball.image_dir(), &stamp); diff --git a/src/bootstrap/src/core/builder/mod.rs b/src/bootstrap/src/core/builder/mod.rs index 5e55df67f5c15..4f1bed13c13e7 100644 --- a/src/bootstrap/src/core/builder/mod.rs +++ b/src/bootstrap/src/core/builder/mod.rs @@ -22,6 +22,7 @@ use crate::core::build_steps::{ }; use crate::core::config::flags::Subcommand; use crate::core::config::{DryRun, TargetSelection}; +use crate::utils::build_stamp::BuildStamp; use crate::utils::cache::Cache; use crate::utils::exec::{BootstrapCommand, ExecutionContext, command}; use crate::utils::helpers::{self, LldThreads, add_dylib_path, exe, libdir, linker_args, t}; @@ -1412,6 +1413,8 @@ impl<'a> Builder<'a> { /// The standard library will be linked to the sysroot of the passed compiler. /// /// Prefer using this method rather than manually invoking `Std::new`. + /// + /// Returns an optional build stamp, if libstd was indeed built. #[cfg_attr( feature = "tracing", instrument( @@ -1425,7 +1428,7 @@ impl<'a> Builder<'a> { ), ), )] - pub fn std(&self, compiler: Compiler, target: TargetSelection) { + pub fn std(&self, compiler: Compiler, target: TargetSelection) -> Option { // FIXME: make the `Std` step return some type-level "proof" that std was indeed built, // and then require passing that to all Cargo invocations that we do. @@ -1444,10 +1447,11 @@ You have to build a stage1 compiler for `{}` first, and then use it to build a s // We still need to link the prebuilt standard library into the ephemeral stage0 sysroot self.ensure(StdLink::from_std(Std::new(compiler, target), compiler)); + None } else { // This step both compiles the std and links it into the compiler's sysroot. // Yes, it's quite magical and side-effecty.. would be nice to refactor later. - self.ensure(Std::new(compiler, target)); + self.ensure(Std::new(compiler, target)) } } From 600d9bf1497c0315107ed6e9c613017e9697100a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 23 Aug 2025 14:17:51 +0200 Subject: [PATCH 29/30] Use correct mode when printing a build message for std documentation --- src/bootstrap/src/core/build_steps/doc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index e0cea046c59a7..8c20c8c479af0 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -784,7 +784,7 @@ fn doc_std( let description = format!("library{} in {} format", crate_description(requested_crates), format.as_str()); - let _guard = builder.msg(Kind::Doc, description, None, build_compiler, target); + let _guard = builder.msg(Kind::Doc, description, Mode::Std, build_compiler, target); cargo.into_cmd().run(builder); builder.cp_link_r(&out_dir, out); From 412734de2943c700a7606bd4a1fe81f58461bca7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jakub=20Ber=C3=A1nek?= Date: Sat, 23 Aug 2025 14:18:30 +0200 Subject: [PATCH 30/30] Allow running rust-installer (and other tools) multiple times with the same arguments --- src/bootstrap/src/core/build_steps/tool.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/tool.rs b/src/bootstrap/src/core/build_steps/tool.rs index b62c9a906b79c..c10b82536467d 100644 --- a/src/bootstrap/src/core/build_steps/tool.rs +++ b/src/bootstrap/src/core/build_steps/tool.rs @@ -1581,6 +1581,10 @@ impl Builder<'_> { /// `host`. pub fn tool_cmd(&self, tool: Tool) -> BootstrapCommand { let mut cmd = command(self.tool_exe(tool)); + + // Do not cache tool invocations, as they can have side effects + cmd.do_not_cache(); + let compiler = self.compiler(0, self.config.host_target); let host = &compiler.host; // Prepares the `cmd` provided to be able to run the `compiler` provided.