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] 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 7b3e5db58f80..8cad5b920b91 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 299ed8442aec..3c322256cf27 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 5e55df67f5c1..4f1bed13c13e 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)) } }