|
| 1 | +From b1b6c0a48f0009d1ef192a2accbbc899624c9c8a Mon Sep 17 00:00:00 2001 |
| 2 | +From: Sungjoon Moon < [email protected]> |
| 3 | +Date: Sat, 13 Sep 2025 04:35:33 +0900 |
| 4 | +Subject: [PATCH] Enable building/disting standard library in stage 0 |
| 5 | + |
| 6 | +Reference: https://github.com/rust-lang/rust/pull/145876 |
| 7 | +Disabled from here: https://github.com/rust-lang/rust/commit/52882f6522ae9f34f1d574b2efabc4b18e691ae0 |
| 8 | +--- |
| 9 | + src/bootstrap/src/core/build_steps/compile.rs | 99 +++++++++++-------- |
| 10 | + 1 file changed, 58 insertions(+), 41 deletions(-) |
| 11 | + |
| 12 | +diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs |
| 13 | +index f6efb23e8d8..0371211348b 100644 |
| 14 | +--- a/src/bootstrap/src/core/build_steps/compile.rs |
| 15 | ++++ b/src/bootstrap/src/core/build_steps/compile.rs |
| 16 | +@@ -150,8 +150,13 @@ fn make_run(run: RunConfig<'_>) { |
| 17 | + fn run(self, builder: &Builder<'_>) { |
| 18 | + let target = self.target; |
| 19 | + |
| 20 | +- // We already have std ready to be used for stage 0. |
| 21 | +- if self.compiler.stage == 0 { |
| 22 | ++ // In most cases, we already have the std ready to be used for stage 0. |
| 23 | ++ // However, if we are doing a local rebuild (so the build compiler can compile the standard |
| 24 | ++ // library even on stage 0), and we're cross-compiling (so the stage0 standard library for |
| 25 | ++ // *target* is not available), we still allow the stdlib to be built here. |
| 26 | ++ if self.compiler.stage == 0 |
| 27 | ++ && !(builder.local_rebuild && target != builder.host_target) |
| 28 | ++ { |
| 29 | + let compiler = self.compiler; |
| 30 | + builder.ensure(StdLink::from_std(self, compiler)); |
| 31 | + |
| 32 | +@@ -204,13 +209,7 @@ fn run(self, builder: &Builder<'_>) { |
| 33 | + let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target); |
| 34 | + trace!(?compiler_to_use); |
| 35 | + |
| 36 | +- if compiler_to_use != compiler |
| 37 | +- // Never uplift std unless we have compiled stage 1; if stage 1 is compiled, |
| 38 | +- // uplift it from there. |
| 39 | +- // |
| 40 | +- // FIXME: improve `fn compiler_for` to avoid adding stage condition here. |
| 41 | +- && compiler.stage > 1 |
| 42 | +- { |
| 43 | ++ if compiler_to_use != compiler { |
| 44 | + trace!(?compiler_to_use, ?compiler, "compiler != compiler_to_use, uplifting library"); |
| 45 | + |
| 46 | + builder.ensure(Std::new(compiler_to_use, target)); |
| 47 | +@@ -235,6 +234,8 @@ fn run(self, builder: &Builder<'_>) { |
| 48 | + return; |
| 49 | + } |
| 50 | + |
| 51 | ++ |
| 52 | ++ |
| 53 | + trace!( |
| 54 | + ?compiler_to_use, |
| 55 | + ?compiler, |
| 56 | +@@ -243,6 +244,27 @@ fn run(self, builder: &Builder<'_>) { |
| 57 | + |
| 58 | + target_deps.extend(self.copy_extra_objects(builder, &compiler, target)); |
| 59 | + |
| 60 | ++ // The LLD wrappers and `rust-lld` are self-contained linking components that can be |
| 61 | ++ // necessary to link the stdlib on some targets. We'll also need to copy these binaries to |
| 62 | ++ // the `stage0-sysroot` to ensure the linker is found when bootstrapping on such a target. |
| 63 | ++ if compiler.stage == 0 && builder.config.is_host_target(compiler.host) { |
| 64 | ++ trace!( |
| 65 | ++ "(build == host) copying linking components to `stage0-sysroot` for bootstrapping" |
| 66 | ++ ); |
| 67 | ++ // We want to copy the host `bin` folder within the `rustlib` folder in the sysroot. |
| 68 | ++ let src_sysroot_bin = builder |
| 69 | ++ .rustc_snapshot_sysroot() |
| 70 | ++ .join("lib") |
| 71 | ++ .join("rustlib") |
| 72 | ++ .join(compiler.host) |
| 73 | ++ .join("bin"); |
| 74 | ++ if src_sysroot_bin.exists() { |
| 75 | ++ let target_sysroot_bin = builder.sysroot_target_bindir(compiler, target); |
| 76 | ++ t!(fs::create_dir_all(&target_sysroot_bin)); |
| 77 | ++ builder.cp_link_r(&src_sysroot_bin, &target_sysroot_bin); |
| 78 | ++ } |
| 79 | ++ } |
| 80 | ++ |
| 81 | + // We build a sysroot for mir-opt tests using the same trick that Miri does: A check build |
| 82 | + // with -Zalways-encode-mir. This frees us from the need to have a target linker, and the |
| 83 | + // fact that this is a check build integrates nicely with run_cargo. |
| 84 | +@@ -762,16 +784,23 @@ fn run(self, builder: &Builder<'_>) { |
| 85 | + (libdir, hostdir) |
| 86 | + }; |
| 87 | + |
| 88 | +- let is_downloaded_beta_stage0 = builder |
| 89 | +- .build |
| 90 | +- .config |
| 91 | +- .initial_rustc |
| 92 | +- .starts_with(builder.out.join(compiler.host).join("stage0/bin")); |
| 93 | ++ add_to_sysroot( |
| 94 | ++ builder, |
| 95 | ++ &libdir, |
| 96 | ++ &hostdir, |
| 97 | ++ &build_stamp::libstd_stamp(builder, compiler, target), |
| 98 | ++ ); |
| 99 | + |
| 100 | + // Special case for stage0, to make `rustup toolchain link` and `x dist --stage 0` |
| 101 | + // work for stage0-sysroot. We only do this if the stage0 compiler comes from beta, |
| 102 | + // and is not set to a custom path. |
| 103 | +- if compiler.stage == 0 && is_downloaded_beta_stage0 { |
| 104 | ++ if compiler.stage == 0 |
| 105 | ++ && builder |
| 106 | ++ .build |
| 107 | ++ .config |
| 108 | ++ .initial_rustc |
| 109 | ++ .starts_with(builder.out.join(compiler.host).join("stage0/bin")) |
| 110 | ++ { |
| 111 | + // Copy bin files from stage0/bin to stage0-sysroot/bin |
| 112 | + let sysroot = builder.out.join(compiler.host).join("stage0-sysroot"); |
| 113 | + |
| 114 | +@@ -781,9 +810,21 @@ fn run(self, builder: &Builder<'_>) { |
| 115 | + t!(fs::create_dir_all(&sysroot_bin_dir)); |
| 116 | + builder.cp_link_r(&stage0_bin_dir, &sysroot_bin_dir); |
| 117 | + |
| 118 | ++ // Copy all files from stage0/lib to stage0-sysroot/lib |
| 119 | + let stage0_lib_dir = builder.out.join(host).join("stage0/lib"); |
| 120 | +- t!(fs::create_dir_all(sysroot.join("lib"))); |
| 121 | +- builder.cp_link_r(&stage0_lib_dir, &sysroot.join("lib")); |
| 122 | ++ if let Ok(files) = fs::read_dir(stage0_lib_dir) { |
| 123 | ++ for file in files { |
| 124 | ++ let file = t!(file); |
| 125 | ++ let path = file.path(); |
| 126 | ++ if path.is_file() { |
| 127 | ++ builder.copy_link( |
| 128 | ++ &path, |
| 129 | ++ &sysroot.join("lib").join(path.file_name().unwrap()), |
| 130 | ++ FileType::Regular, |
| 131 | ++ ); |
| 132 | ++ } |
| 133 | ++ } |
| 134 | ++ } |
| 135 | + |
| 136 | + // Copy codegen-backends from stage0 |
| 137 | + let sysroot_codegen_backends = builder.sysroot_codegen_backends(compiler); |
| 138 | +@@ -797,30 +838,6 @@ fn run(self, builder: &Builder<'_>) { |
| 139 | + if stage0_codegen_backends.exists() { |
| 140 | + builder.cp_link_r(&stage0_codegen_backends, &sysroot_codegen_backends); |
| 141 | + } |
| 142 | +- } else if compiler.stage == 0 { |
| 143 | +- let sysroot = builder.out.join(compiler.host.triple).join("stage0-sysroot"); |
| 144 | +- |
| 145 | +- if builder.local_rebuild { |
| 146 | +- // On local rebuilds this path might be a symlink to the project root, |
| 147 | +- // which can be read-only (e.g., on CI). So remove it before copying |
| 148 | +- // the stage0 lib. |
| 149 | +- let _ = fs::remove_dir_all(sysroot.join("lib/rustlib/src/rust")); |
| 150 | +- } |
| 151 | +- |
| 152 | +- builder.cp_link_r(&builder.initial_sysroot.join("lib"), &sysroot.join("lib")); |
| 153 | +- } else { |
| 154 | +- if builder.download_rustc() { |
| 155 | +- // Ensure there are no CI-rustc std artifacts. |
| 156 | +- let _ = fs::remove_dir_all(&libdir); |
| 157 | +- let _ = fs::remove_dir_all(&hostdir); |
| 158 | +- } |
| 159 | +- |
| 160 | +- add_to_sysroot( |
| 161 | +- builder, |
| 162 | +- &libdir, |
| 163 | +- &hostdir, |
| 164 | +- &build_stamp::libstd_stamp(builder, compiler, target), |
| 165 | +- ); |
| 166 | + } |
| 167 | + } |
| 168 | + } |
| 169 | +-- |
| 170 | +2.51.0 |
| 171 | + |
0 commit comments