Skip to content

Commit b1b6c0a

Browse files
committed
Enable building/disting standard library in stage 0
Reference: rust-lang#145876 Disabled from here: rust-lang@52882f6
1 parent 2948388 commit b1b6c0a

File tree

1 file changed

+58
-41
lines changed

1 file changed

+58
-41
lines changed

src/bootstrap/src/core/build_steps/compile.rs

Lines changed: 58 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -150,8 +150,13 @@ impl Step for Std {
150150
fn run(self, builder: &Builder<'_>) {
151151
let target = self.target;
152152

153-
// We already have std ready to be used for stage 0.
154-
if self.compiler.stage == 0 {
153+
// In most cases, we already have the std ready to be used for stage 0.
154+
// However, if we are doing a local rebuild (so the build compiler can compile the standard
155+
// library even on stage 0), and we're cross-compiling (so the stage0 standard library for
156+
// *target* is not available), we still allow the stdlib to be built here.
157+
if self.compiler.stage == 0
158+
&& !(builder.local_rebuild && target != builder.host_target)
159+
{
155160
let compiler = self.compiler;
156161
builder.ensure(StdLink::from_std(self, compiler));
157162

@@ -204,13 +209,7 @@ impl Step for Std {
204209
let compiler_to_use = builder.compiler_for(compiler.stage, compiler.host, target);
205210
trace!(?compiler_to_use);
206211

207-
if compiler_to_use != compiler
208-
// Never uplift std unless we have compiled stage 1; if stage 1 is compiled,
209-
// uplift it from there.
210-
//
211-
// FIXME: improve `fn compiler_for` to avoid adding stage condition here.
212-
&& compiler.stage > 1
213-
{
212+
if compiler_to_use != compiler {
214213
trace!(?compiler_to_use, ?compiler, "compiler != compiler_to_use, uplifting library");
215214

216215
builder.ensure(Std::new(compiler_to_use, target));
@@ -235,6 +234,8 @@ impl Step for Std {
235234
return;
236235
}
237236

237+
238+
238239
trace!(
239240
?compiler_to_use,
240241
?compiler,
@@ -243,6 +244,27 @@ impl Step for Std {
243244

244245
target_deps.extend(self.copy_extra_objects(builder, &compiler, target));
245246

247+
// The LLD wrappers and `rust-lld` are self-contained linking components that can be
248+
// necessary to link the stdlib on some targets. We'll also need to copy these binaries to
249+
// the `stage0-sysroot` to ensure the linker is found when bootstrapping on such a target.
250+
if compiler.stage == 0 && builder.config.is_host_target(compiler.host) {
251+
trace!(
252+
"(build == host) copying linking components to `stage0-sysroot` for bootstrapping"
253+
);
254+
// We want to copy the host `bin` folder within the `rustlib` folder in the sysroot.
255+
let src_sysroot_bin = builder
256+
.rustc_snapshot_sysroot()
257+
.join("lib")
258+
.join("rustlib")
259+
.join(compiler.host)
260+
.join("bin");
261+
if src_sysroot_bin.exists() {
262+
let target_sysroot_bin = builder.sysroot_target_bindir(compiler, target);
263+
t!(fs::create_dir_all(&target_sysroot_bin));
264+
builder.cp_link_r(&src_sysroot_bin, &target_sysroot_bin);
265+
}
266+
}
267+
246268
// We build a sysroot for mir-opt tests using the same trick that Miri does: A check build
247269
// with -Zalways-encode-mir. This frees us from the need to have a target linker, and the
248270
// fact that this is a check build integrates nicely with run_cargo.
@@ -762,16 +784,23 @@ impl Step for StdLink {
762784
(libdir, hostdir)
763785
};
764786

765-
let is_downloaded_beta_stage0 = builder
766-
.build
767-
.config
768-
.initial_rustc
769-
.starts_with(builder.out.join(compiler.host).join("stage0/bin"));
787+
add_to_sysroot(
788+
builder,
789+
&libdir,
790+
&hostdir,
791+
&build_stamp::libstd_stamp(builder, compiler, target),
792+
);
770793

771794
// Special case for stage0, to make `rustup toolchain link` and `x dist --stage 0`
772795
// work for stage0-sysroot. We only do this if the stage0 compiler comes from beta,
773796
// and is not set to a custom path.
774-
if compiler.stage == 0 && is_downloaded_beta_stage0 {
797+
if compiler.stage == 0
798+
&& builder
799+
.build
800+
.config
801+
.initial_rustc
802+
.starts_with(builder.out.join(compiler.host).join("stage0/bin"))
803+
{
775804
// Copy bin files from stage0/bin to stage0-sysroot/bin
776805
let sysroot = builder.out.join(compiler.host).join("stage0-sysroot");
777806

@@ -781,9 +810,21 @@ impl Step for StdLink {
781810
t!(fs::create_dir_all(&sysroot_bin_dir));
782811
builder.cp_link_r(&stage0_bin_dir, &sysroot_bin_dir);
783812

813+
// Copy all files from stage0/lib to stage0-sysroot/lib
784814
let stage0_lib_dir = builder.out.join(host).join("stage0/lib");
785-
t!(fs::create_dir_all(sysroot.join("lib")));
786-
builder.cp_link_r(&stage0_lib_dir, &sysroot.join("lib"));
815+
if let Ok(files) = fs::read_dir(stage0_lib_dir) {
816+
for file in files {
817+
let file = t!(file);
818+
let path = file.path();
819+
if path.is_file() {
820+
builder.copy_link(
821+
&path,
822+
&sysroot.join("lib").join(path.file_name().unwrap()),
823+
FileType::Regular,
824+
);
825+
}
826+
}
827+
}
787828

788829
// Copy codegen-backends from stage0
789830
let sysroot_codegen_backends = builder.sysroot_codegen_backends(compiler);
@@ -797,30 +838,6 @@ impl Step for StdLink {
797838
if stage0_codegen_backends.exists() {
798839
builder.cp_link_r(&stage0_codegen_backends, &sysroot_codegen_backends);
799840
}
800-
} else if compiler.stage == 0 {
801-
let sysroot = builder.out.join(compiler.host.triple).join("stage0-sysroot");
802-
803-
if builder.local_rebuild {
804-
// On local rebuilds this path might be a symlink to the project root,
805-
// which can be read-only (e.g., on CI). So remove it before copying
806-
// the stage0 lib.
807-
let _ = fs::remove_dir_all(sysroot.join("lib/rustlib/src/rust"));
808-
}
809-
810-
builder.cp_link_r(&builder.initial_sysroot.join("lib"), &sysroot.join("lib"));
811-
} else {
812-
if builder.download_rustc() {
813-
// Ensure there are no CI-rustc std artifacts.
814-
let _ = fs::remove_dir_all(&libdir);
815-
let _ = fs::remove_dir_all(&hostdir);
816-
}
817-
818-
add_to_sysroot(
819-
builder,
820-
&libdir,
821-
&hostdir,
822-
&build_stamp::libstd_stamp(builder, compiler, target),
823-
);
824841
}
825842
}
826843
}

0 commit comments

Comments
 (0)