@@ -14,7 +14,7 @@ It must have been written in a different language. In Rust's case it was
14
14
only way to build a modern version of rustc is a slightly less modern
15
15
version.
16
16
17
- This is exactly how ` x.py ` works: it downloads the current ` beta ` release of
17
+ This is exactly how ` x.py ` works: it downloads the current beta release of
18
18
rustc, then uses it to compile the new compiler.
19
19
20
20
## Stages of bootstrapping
@@ -71,6 +71,8 @@ These defaults are as follows:
71
71
72
72
You can always override the stage by passing ` --stage N ` explicitly.
73
73
74
+ For more information about stages, [ see below] ( #understanding-stages-of-bootstrap ) .
75
+
74
76
## Complications of bootstrapping
75
77
76
78
Since the build system uses the current beta compiler to build the stage-1
@@ -122,50 +124,135 @@ contribution [here][bootstrap-build].
122
124
123
125
## Understanding stages of bootstrap
124
126
125
- This is a detailed look into the separate bootstrap stages. When running
126
- ` x.py ` you will see output such as:
127
-
128
- ``` txt
129
- Building stage0 std artifacts
130
- Copying stage0 std from stage0
131
- Building stage0 compiler artifacts
132
- Copying stage0 rustc from stage0
133
- Building LLVM for x86_64-apple-darwin
134
- Building stage0 codegen artifacts
135
- Assembling stage1 compiler
136
- Building stage1 std artifacts
137
- Copying stage1 std from stage1
138
- Building stage1 compiler artifacts
139
- Copying stage1 rustc from stage1
140
- Building stage1 codegen artifacts
141
- Assembling stage2 compiler
142
- Uplifting stage1 std
143
- Copying stage2 std from stage1
144
- Generating unstable book md files
145
- Building stage0 tool unstable-book-gen
146
- Building stage0 tool rustbook
147
- Documenting standalone
148
- Building rustdoc for stage2
149
- Documenting book redirect pages
150
- Documenting stage2 std
151
- Building rustdoc for stage1
152
- Documenting stage2 whitelisted compiler
153
- Documenting stage2 compiler
154
- Documenting stage2 rustdoc
155
- Documenting error index
156
- Uplifting stage1 rustc
157
- Copying stage2 rustc from stage1
158
- Building stage2 tool error_index_generator
159
- ```
127
+ ### Overview
128
+
129
+ This is a detailed look into the separate bootstrap stages.
130
+
131
+ The convention ` x.py ` uses is that:
132
+ - A ` --stage N ` flag means to run the stage N compiler (` stageN/rustc ` ).
133
+ - A "stage N artifact" is a build artifact that is _ produced_ by the stage N compiler.
134
+ - The "stage (N+1) compiler" is assembled from "stage N artifacts". This
135
+ process is called _ uplifting_ .
136
+
137
+ #### Build artifacts
138
+
139
+ Anything you can build with ` x.py ` is a _ build artifact_ .
140
+ Build artifacts include, but are not limited to:
141
+
142
+ - binaries, like ` stage0-rustc/rustc-main `
143
+ - shared objects, like ` stage0-sysroot/rustlib/libstd-6fae108520cf72fe.so `
144
+ - [ rlib] files, like ` stage0-sysroot/rustlib/libstd-6fae108520cf72fe.rlib `
145
+ - HTML files generated by rustdoc, like ` doc/std `
146
+
147
+ [ rlib ] : ../serialization.md
148
+
149
+ #### Examples
150
+
151
+ - ` x.py build --stage 0 ` means to build with the beta ` rustc ` .
152
+ - ` x.py doc --stage 0 ` means to document using the beta ` rustdoc ` .
153
+ - ` x.py test --stage 0 library/std ` means to run tests on the standard library
154
+ without building ` rustc ` from source ('build with stage 0, then test the
155
+ artifacts'). If you're working on the standard library, this is normally the
156
+ test command you want.
157
+ - ` x.py test src/test/ui ` means to build the stage 1 compiler and run
158
+ ` compiletest ` on it. If you're working on the compiler, this is normally the
159
+ test command you want.
160
+
161
+ #### Examples of what * not* to do
162
+
163
+ - ` x.py test --stage 0 src/test/ui ` is not meaningful: it runs tests on the
164
+ _ beta_ compiler and doesn't build ` rustc ` from source. Use ` test src/test/ui `
165
+ instead, which builds stage 1 from source.
166
+ - ` x.py test --stage 0 compiler/rustc ` builds the compiler but runs no tests:
167
+ it's running ` cargo test -p rustc ` , but cargo doesn't understand Rust's
168
+ tests. You shouldn't need to use this, use ` test ` instead (without arguments).
169
+ - ` x.py build --stage 0 compiler/rustc ` builds the compiler, but does not make
170
+ it usable: the build artifacts are not assembled into the final compiler
171
+ ([ #73519 ] ). Use ` x.py build library/std ` instead, which puts the compiler in
172
+ ` stage1/rustc ` .
173
+
174
+ [ #73519 ] : https://github.com/rust-lang/rust/issues/73519
175
+
176
+ ### Building vs. Running
177
+
160
178
161
- A deeper look into ` x.py ` 's phases can be seen here:
179
+ Note that ` build --stage N compiler/rustc ` ** does not** build the stage N compiler:
180
+ instead it builds the stage _ N+1_ compiler _ using_ the stage N compiler.
181
+
182
+ In short, _ stage 0 uses the stage0 compiler to create stage0 artifacts which
183
+ will later be uplifted to be the stage1 compiler_ .
184
+
185
+ In each stage, two major steps are performed:
186
+
187
+ 1 . ` std ` is compiled by the stage N compiler.
188
+ 2 . That ` std ` is linked to programs built by the stage N compiler, including
189
+ the stage N artifacts (stage (N+1) compiler).
190
+
191
+ This is somewhat intuitive if one thinks of the stage N artifacts as "just"
192
+ another program we are building with the stage N compiler:
193
+ ` build --stage N compiler/rustc ` is linking the stage N artifacts to the ` std `
194
+ built by the stage N compiler.
195
+
196
+ Here is a chart of a full build using ` x.py ` :
162
197
163
198
<img alt =" A diagram of the rustc compilation phases " src =" ../img/rustc_stages.svg " class =" center " />
164
199
165
200
Keep in mind this diagram is a simplification, i.e. ` rustdoc ` can be built at
166
201
different stages, the process is a bit different when passing flags such as
167
202
` --keep-stage ` , or if there are non-host targets.
168
203
204
+ The stage 2 compiler is what is shipped to end-users.
205
+
206
+ ### Stages and ` std `
207
+
208
+ Note that there are two ` std ` libraries in play here:
209
+ 1 . The library _ linked_ to ` stageN/rustc ` , which was built by stage N-1 (stage N-1 ` std ` )
210
+ 2 . The library _ used to compile programs_ with ` stageN/rustc ` , which was
211
+ built by stage N (stage N ` std ` ).
212
+
213
+ Stage N ` std ` is pretty much necessary for any useful work with the stage N compiler.
214
+ Without it, you can only compile programs with ` #![no_core] ` -- not terribly useful!
215
+
216
+ The reason these need to be different is because they aren't necessarily ABI-compatible:
217
+ there could be a new layout optimizations, changes to MIR, or other changes
218
+ to Rust metadata on nightly that aren't present in beta.
219
+
220
+ This is also where ` --keep-stage 1 library/std ` comes into play. Since most
221
+ changes to the compiler don't actually change the ABI, once you've produced a
222
+ ` std ` in stage 1, you can probably just reuse it with a different compiler.
223
+ If the ABI hasn't changed, you're good to go, no need to spend time
224
+ recompiling that ` std ` .
225
+ ` --keep-stage ` simply assumes the previous compile is fine and copies those
226
+ artifacts into the appropriate place, skipping the cargo invocation.
227
+
228
+ ### Cross-compiling
229
+
230
+ Building stage2 ` std ` is different depending on whether you are cross-compiling or not
231
+ (see in the table how stage2 only builds non-host ` std ` targets).
232
+ This is because ` x.py ` uses a trick: if ` HOST ` and ` TARGET ` are the same,
233
+ it will reuse stage1 ` std ` for stage2! This is sound because stage1 ` std `
234
+ was compiled with the stage1 compiler, i.e. a compiler using the source code
235
+ you currently have checked out. So it should be identical (and therefore ABI-compatible)
236
+ to the ` std ` that ` stage2/rustc ` would compile.
237
+
238
+ However, when cross-compiling, stage1 ` std ` will only run on the host.
239
+ So the stage2 compiler has to recompile ` std ` for the target.
240
+
241
+ ### Why does only libstd use ` cfg(bootstrap) ` ?
242
+
243
+ The ` rustc ` generated by the stage0 compiler is linked to the freshly-built
244
+ ` std ` , which means that for the most part only ` std ` needs to be cfg-gated,
245
+ so that ` rustc ` can use features added to std immediately after their addition,
246
+ without need for them to get into the downloaded beta.
247
+
248
+ Note this is different from any other Rust program: stage1 ` rustc `
249
+ is built by the _ beta_ compiler, but using the _ master_ version of libstd!
250
+
251
+ The only time ` rustc ` uses ` cfg(bootstrap) ` is when it adds internal lints
252
+ that use diagnostic items. This happens very rarely.
253
+
254
+ ### Directories and artifacts generated by x.py
255
+
169
256
The following tables indicate the outputs of various stage actions:
170
257
171
258
| Stage 0 Action | Output |
@@ -178,7 +265,7 @@ The following tables indicate the outputs of various stage actions:
178
265
| copy ` stage0-rustc (except executable) ` | ` build/HOST/stage0-sysroot/lib/rustlib/HOST ` |
179
266
| build ` llvm ` | ` build/HOST/llvm ` |
180
267
| ` stage0 ` builds ` codegen ` with ` stage0-sysroot ` | ` build/HOST/stage0-codegen/HOST ` |
181
- | ` stage0 ` builds ` rustdoc ` with ` stage0-sysroot ` | ` build/HOST/stage0-tools/HOST ` |
268
+ | ` stage0 ` builds ` rustdoc ` , ` clippy ` , ` miri ` , with ` stage0-sysroot ` | ` build/HOST/stage0-tools/HOST ` |
182
269
183
270
` --stage=0 ` stops here.
184
271
@@ -201,93 +288,19 @@ The following tables indicate the outputs of various stage actions:
201
288
| copy (uplift) ` stage1-sysroot ` | ` build/HOST/stage2/lib and build/HOST/stage2/lib/rustlib/HOST ` |
202
289
| ` stage2 ` builds ` test ` /` std ` (not HOST targets) | ` build/HOST/stage2-std/TARGET ` |
203
290
| copy ` stage2-std ` (not HOST targets) | ` build/HOST/stage2/lib/rustlib/TARGET ` |
204
- | ` stage2 ` builds ` rustdoc ` | ` build/HOST/stage2-tools/HOST ` |
291
+ | ` stage2 ` builds ` rustdoc ` , ` clippy ` , ` miri ` | ` build/HOST/stage2-tools/HOST ` |
205
292
| copy ` rustdoc ` | ` build/HOST/stage2/bin ` |
206
293
207
294
` --stage=2 ` stops here.
208
295
209
- Note that the convention ` x.py ` uses is that:
210
- - A "stage N artifact" is an artifact that is _ produced_ by the stage N compiler.
211
- - The "stage (N+1) compiler" is assembled from "stage N artifacts".
212
- - A ` --stage N ` flag means build _ with_ stage N.
213
-
214
- In short, _ stage 0 uses the stage0 compiler to create stage0 artifacts which
215
- will later be uplifted to stage1_ .
216
-
217
- Every time any of the main artifacts (` std ` and ` rustc ` ) are compiled, two
218
- steps are performed.
219
- When ` std ` is compiled by a stage N compiler, that ` std ` will be linked to
220
- programs built by the stage N compiler (including ` rustc ` built later
221
- on). It will also be used by the stage (N+1) compiler to link against itself.
222
- This is somewhat intuitive if one thinks of the stage (N+1) compiler as "just"
223
- another program we are building with the stage N compiler. In some ways, ` rustc `
224
- (the binary, not the ` rustbuild ` step) could be thought of as one of the few
225
- ` no_core ` binaries out there.
226
-
227
- So "stage0 std artifacts" are in fact the output of the downloaded stage0
228
- compiler, and are going to be used for anything built by the stage0 compiler:
229
- e.g. ` rustc ` artifacts. When it announces that it is "building stage1
230
- std artifacts" it has moved on to the next bootstrapping phase. This pattern
231
- continues in latter stages.
232
-
233
- Also note that building host ` std ` and target ` std ` are different based on the
234
- stage (e.g. see in the table how stage2 only builds non-host ` std ` targets.
235
- This is because during stage2, the host ` std ` is uplifted from the "stage 1"
236
- ` std ` -- specifically, when "Building stage 1 artifacts" is announced, it is
237
- later copied into stage2 as well (both the compiler's ` libdir ` and the
238
- ` sysroot ` ).
239
-
240
- This ` std ` is pretty much necessary for any useful work with the compiler.
241
- Specifically, it's used as the ` std ` for programs compiled by the newly compiled
242
- compiler (so when you compile ` fn main() { } ` it is linked to the last ` std `
243
- compiled with ` x.py build library/std ` ).
244
-
245
- The ` rustc ` generated by the stage0 compiler is linked to the freshly-built
246
- ` std ` , which means that for the most part only ` std ` needs to be cfg-gated,
247
- so that ` rustc ` can use featured added to std immediately after their addition,
248
- without need for them to get into the downloaded beta. The ` std ` built by the
249
- ` stage1/bin/rustc ` compiler, also known as "stage1 std artifacts", is not
250
- necessarily ABI-compatible with that compiler.
251
- That is, the ` rustc ` binary most likely could not use this ` std ` itself.
252
- It is however ABI-compatible with any programs that the ` stage1/bin/rustc `
253
- binary builds (including itself), so in that sense they're paired.
254
-
255
- This is also where ` --keep-stage 1 library/std ` comes into play. Since most
256
- changes to the compiler don't actually change the ABI, once you've produced a
257
- ` std ` in stage 1, you can probably just reuse it with a different compiler.
258
- If the ABI hasn't changed, you're good to go, no need to spend the time
259
- recompiling that ` std ` .
260
- ` --keep-stage ` simply assumes the previous compile is fine and copies those
261
- artifacts into the appropriate place, skipping the cargo invocation.
262
-
263
- The reason we first build ` std ` , then ` rustc ` , is largely just
264
- because we want to minimize ` cfg(stage0) ` in the code for ` rustc ` .
265
- Currently ` rustc ` is always linked against a "new" ` std ` so it doesn't
266
- ever need to be concerned with differences in std; it can assume that the std is
267
- as fresh as possible.
268
-
269
- The reason we need to build it twice is because of ABI compatibility.
270
- The beta compiler has it's own ABI, and then the ` stage1/bin/rustc ` compiler
271
- will produce programs/libraries with the new ABI.
272
- We used to build three times, but because we assume that the ABI is constant
273
- within a codebase, we presume that the libraries produced by the "stage2"
274
- compiler (produced by the ` stage1/bin/rustc ` compiler) is ABI-compatible with
275
- the ` stage1/bin/rustc ` compiler's produced libraries.
276
- What this means is that we can skip that final compilation -- and simply use the
277
- same libraries as the ` stage2/bin/rustc ` compiler uses itself for programs it
278
- links against.
279
-
280
- This ` stage2/bin/rustc ` compiler is shipped to end-users, along with the
281
- ` stage 1 {std,rustc} ` artifacts.
282
-
283
296
## Passing stage-specific flags to ` rustc `
284
297
285
298
` x.py ` allows you to pass stage-specific flags to ` rustc ` when bootstrapping.
286
299
The ` RUSTFLAGS_STAGE_0 ` , ` RUSTFLAGS_STAGE_1 ` and ` RUSTFLAGS_STAGE_2 `
287
300
environment variables pass the given flags when building stage 0, 1, and 2
288
301
artifacts respectively.
289
302
290
- Additionally, the ` RUSTFLAGS_STAGE_NOT_0 ` variable, as its name suggests, pass
303
+ Additionally, the ` RUSTFLAGS_STAGE_NOT_0 ` variable, as its name suggests, passes
291
304
the given arguments if the stage is not 0.
292
305
293
306
## Environment Variables
0 commit comments