1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
|
From b1b6c0a48f0009d1ef192a2accbbc899624c9c8a Mon Sep 17 00:00:00 2001
From: Sungjoon Moon <sumoon@seoulsaram.org>
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
|