Handle uplifting in libstd dist step

This commit is contained in:
Jakub Beránek 2025-08-23 11:17:35 +02:00
parent 21c30eac49
commit a62488bb27
No known key found for this signature in database
GPG key ID: 909CD0D26483516B
3 changed files with 23 additions and 12 deletions

View file

@ -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<BuildStamp>;
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<StepMetadata> {

View file

@ -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);

View file

@ -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<BuildStamp> {
// 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))
}
}