commit:     c906cb2b3d0db76e35471454df188bc390e24460
Author:     Sungjoon Moon <sumoon <AT> seoulsaram <DOT> org>
AuthorDate: Fri Sep 12 19:41:38 2025 +0000
Commit:     Sam James <sam <AT> gentoo <DOT> org>
CommitDate: Sun Sep 14 10:34:11 2025 +0000
URL:        https://gitweb.gentoo.org/repo/gentoo.git/commit/?id=c906cb2b

sys-devel/rust-std: Enable stage 0 build for 1.89.0

Rust changed bootstrap design since version 1.89.0, and it doesn't build stage0 
stdlib anymore:
https://blog.rust-lang.org/inside-rust/2025/05/29/redesigning-the-initial-bootstrap-sequence/

This upstream PR will fix the issue from 1.91.0:
https://github.com/rust-lang/rust/pull/145876

Closes: https://bugs.gentoo.org/962786
Signed-off-by: Sungjoon Moon <sumoon <AT> seoulsaram.org>
Part-of: https://github.com/gentoo/gentoo/pull/43765
Closes: https://github.com/gentoo/gentoo/pull/43765
Signed-off-by: Sam James <sam <AT> gentoo.org>

 .../files/1.89.0-enable-stage-0-build.patch        | 171 +++++++++++++++++++++
 sys-devel/rust-std/rust-std-1.89.0.ebuild          |   3 +
 2 files changed, 174 insertions(+)

diff --git a/sys-devel/rust-std/files/1.89.0-enable-stage-0-build.patch 
b/sys-devel/rust-std/files/1.89.0-enable-stage-0-build.patch
new file mode 100644
index 000000000000..4198e169fba9
--- /dev/null
+++ b/sys-devel/rust-std/files/1.89.0-enable-stage-0-build.patch
@@ -0,0 +1,171 @@
+From b1b6c0a48f0009d1ef192a2accbbc899624c9c8a Mon Sep 17 00:00:00 2001
+From: Sungjoon Moon <[email protected]>
+Date: Sat, 13 Sep 2025 04:35:33 +0900
+Subject: [PATCH] Enable building/disting standard library in stage 0
+
+Reference: https://github.com/rust-lang/rust/pull/145876
+Disabled from here: 
https://github.com/rust-lang/rust/commit/52882f6522ae9f34f1d574b2efabc4b18e691ae0
+---
+ src/bootstrap/src/core/build_steps/compile.rs | 99 +++++++++++--------
+ 1 file changed, 58 insertions(+), 41 deletions(-)
+
+diff --git a/src/bootstrap/src/core/build_steps/compile.rs 
b/src/bootstrap/src/core/build_steps/compile.rs
+index f6efb23e8d8..0371211348b 100644
+--- a/src/bootstrap/src/core/build_steps/compile.rs
++++ b/src/bootstrap/src/core/build_steps/compile.rs
+@@ -150,8 +150,13 @@ fn make_run(run: RunConfig<'_>) {
+     fn run(self, builder: &Builder<'_>) {
+         let target = self.target;
+ 
+-        // We already have std ready to be used for stage 0.
+-        if self.compiler.stage == 0 {
++        // In most cases, we already have the std ready to be used for stage 
0.
++        // However, if we are doing a local rebuild (so the build compiler 
can compile the standard
++        // library even on stage 0), and we're cross-compiling (so the stage0 
standard library for
++        // *target* is not available), we still allow the stdlib to be built 
here.
++        if self.compiler.stage == 0
++            && !(builder.local_rebuild && target != builder.host_target)
++        {
+             let compiler = self.compiler;
+             builder.ensure(StdLink::from_std(self, compiler));
+ 
+@@ -204,13 +209,7 @@ fn run(self, builder: &Builder<'_>) {
+         let compiler_to_use = builder.compiler_for(compiler.stage, 
compiler.host, target);
+         trace!(?compiler_to_use);
+ 
+-        if compiler_to_use != compiler
+-            // Never uplift std unless we have compiled stage 1; if stage 1 
is compiled,
+-            // uplift it from there.
+-            //
+-            // FIXME: improve `fn compiler_for` to avoid adding stage 
condition here.
+-            && compiler.stage > 1
+-        {
++        if compiler_to_use != compiler {
+             trace!(?compiler_to_use, ?compiler, "compiler != compiler_to_use, 
uplifting library");
+ 
+             builder.ensure(Std::new(compiler_to_use, target));
+@@ -235,6 +234,8 @@ fn run(self, builder: &Builder<'_>) {
+             return;
+         }
+ 
++
++
+         trace!(
+             ?compiler_to_use,
+             ?compiler,
+@@ -243,6 +244,27 @@ fn run(self, builder: &Builder<'_>) {
+ 
+         target_deps.extend(self.copy_extra_objects(builder, &compiler, 
target));
+ 
++        // The LLD wrappers and `rust-lld` are self-contained linking 
components that can be
++        // necessary to link the stdlib on some targets. We'll also need to 
copy these binaries to
++        // the `stage0-sysroot` to ensure the linker is found when 
bootstrapping on such a target.
++        if compiler.stage == 0 && 
builder.config.is_host_target(compiler.host) {
++            trace!(
++                "(build == host) copying linking components to 
`stage0-sysroot` for bootstrapping"
++            );
++            // We want to copy the host `bin` folder within the `rustlib` 
folder in the sysroot.
++            let src_sysroot_bin = builder
++                .rustc_snapshot_sysroot()
++                .join("lib")
++                .join("rustlib")
++                .join(compiler.host)
++                .join("bin");
++            if src_sysroot_bin.exists() {
++                let target_sysroot_bin = 
builder.sysroot_target_bindir(compiler, target);
++                t!(fs::create_dir_all(&target_sysroot_bin));
++                builder.cp_link_r(&src_sysroot_bin, &target_sysroot_bin);
++            }
++        }
++
+         // We build a sysroot for mir-opt tests using the same trick that 
Miri does: A check build
+         // with -Zalways-encode-mir. This frees us from the need to have a 
target linker, and the
+         // fact that this is a check build integrates nicely with run_cargo.
+@@ -762,16 +784,23 @@ fn run(self, builder: &Builder<'_>) {
+             (libdir, hostdir)
+         };
+ 
+-        let is_downloaded_beta_stage0 = builder
+-            .build
+-            .config
+-            .initial_rustc
+-            .starts_with(builder.out.join(compiler.host).join("stage0/bin"));
++        add_to_sysroot(
++            builder,
++            &libdir,
++            &hostdir,
++            &build_stamp::libstd_stamp(builder, compiler, target),
++        );
+ 
+         // Special case for stage0, to make `rustup toolchain link` and `x 
dist --stage 0`
+         // work for stage0-sysroot. We only do this if the stage0 compiler 
comes from beta,
+         // and is not set to a custom path.
+-        if compiler.stage == 0 && is_downloaded_beta_stage0 {
++        if compiler.stage == 0
++            && builder
++                .build
++                .config
++                .initial_rustc
++                
.starts_with(builder.out.join(compiler.host).join("stage0/bin"))
++        {
+             // Copy bin files from stage0/bin to stage0-sysroot/bin
+             let sysroot = 
builder.out.join(compiler.host).join("stage0-sysroot");
+ 
+@@ -781,9 +810,21 @@ fn run(self, builder: &Builder<'_>) {
+             t!(fs::create_dir_all(&sysroot_bin_dir));
+             builder.cp_link_r(&stage0_bin_dir, &sysroot_bin_dir);
+ 
++            // Copy all files from stage0/lib to stage0-sysroot/lib
+             let stage0_lib_dir = builder.out.join(host).join("stage0/lib");
+-            t!(fs::create_dir_all(sysroot.join("lib")));
+-            builder.cp_link_r(&stage0_lib_dir, &sysroot.join("lib"));
++            if let Ok(files) = fs::read_dir(stage0_lib_dir) {
++                for file in files {
++                    let file = t!(file);
++                    let path = file.path();
++                    if path.is_file() {
++                        builder.copy_link(
++                            &path,
++                            
&sysroot.join("lib").join(path.file_name().unwrap()),
++                            FileType::Regular,
++                        );
++                    }
++                }
++            }
+ 
+             // Copy codegen-backends from stage0
+             let sysroot_codegen_backends = 
builder.sysroot_codegen_backends(compiler);
+@@ -797,30 +838,6 @@ fn run(self, builder: &Builder<'_>) {
+             if stage0_codegen_backends.exists() {
+                 builder.cp_link_r(&stage0_codegen_backends, 
&sysroot_codegen_backends);
+             }
+-        } else if compiler.stage == 0 {
+-            let sysroot = 
builder.out.join(compiler.host.triple).join("stage0-sysroot");
+-
+-            if builder.local_rebuild {
+-                // On local rebuilds this path might be a symlink to the 
project root,
+-                // which can be read-only (e.g., on CI). So remove it before 
copying
+-                // the stage0 lib.
+-                let _ = 
fs::remove_dir_all(sysroot.join("lib/rustlib/src/rust"));
+-            }
+-
+-            builder.cp_link_r(&builder.initial_sysroot.join("lib"), 
&sysroot.join("lib"));
+-        } else {
+-            if builder.download_rustc() {
+-                // Ensure there are no CI-rustc std artifacts.
+-                let _ = fs::remove_dir_all(&libdir);
+-                let _ = fs::remove_dir_all(&hostdir);
+-            }
+-
+-            add_to_sysroot(
+-                builder,
+-                &libdir,
+-                &hostdir,
+-                &build_stamp::libstd_stamp(builder, compiler, target),
+-            );
+         }
+     }
+ }
+-- 
+2.51.0
+

diff --git a/sys-devel/rust-std/rust-std-1.89.0.ebuild 
b/sys-devel/rust-std/rust-std-1.89.0.ebuild
index d3494b367846..ac1ac73a0723 100644
--- a/sys-devel/rust-std/rust-std-1.89.0.ebuild
+++ b/sys-devel/rust-std/rust-std-1.89.0.ebuild
@@ -62,6 +62,9 @@ VERIFY_SIG_OPENPGP_KEY_PATH=/usr/share/openpgp-keys/rust.asc
 
 QA_FLAGS_IGNORED="usr/lib/rust/${PV}/rustlib/.*/lib/lib.*.so"
 
+PATCHES=(
+       "${FILESDIR}"/1.89.0-enable-stage-0-build.patch  # remove for >=1.91.0
+)
 #
 # The cross magic
 #

Reply via email to