@@ -14,7 +14,7 @@ It must have been written in a different language. In Rust's case it was
1414only way to build a modern version of rustc is a slightly less modern
1515version.
1616
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
1818rustc, then uses it to compile the new compiler.
1919
2020## Stages of bootstrapping
@@ -71,6 +71,8 @@ These defaults are as follows:
7171
7272You can always override the stage by passing ` --stage N ` explicitly.
7373
74+ For more information about stages, [ see below] ( #understanding-stages-of-bootstrap ) .
75+
7476## Complications of bootstrapping
7577
7678Since the build system uses the current beta compiler to build the stage-1
@@ -122,50 +124,135 @@ contribution [here][bootstrap-build].
122124
123125## Understanding stages of bootstrap
124126
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+
160178
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 ` :
162197
163198<img alt =" A diagram of the rustc compilation phases " src =" ../img/rustc_stages.svg " class =" center " />
164199
165200Keep in mind this diagram is a simplification, i.e. ` rustdoc ` can be built at
166201different stages, the process is a bit different when passing flags such as
167202` --keep-stage ` , or if there are non-host targets.
168203
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+
169256The following tables indicate the outputs of various stage actions:
170257
171258| Stage 0 Action | Output |
@@ -178,7 +265,7 @@ The following tables indicate the outputs of various stage actions:
178265| copy ` stage0-rustc (except executable) ` | ` build/HOST/stage0-sysroot/lib/rustlib/HOST ` |
179266| build ` llvm ` | ` build/HOST/llvm ` |
180267| ` 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 ` |
182269
183270` --stage=0 ` stops here.
184271
@@ -201,93 +288,19 @@ The following tables indicate the outputs of various stage actions:
201288| copy (uplift) ` stage1-sysroot ` | ` build/HOST/stage2/lib and build/HOST/stage2/lib/rustlib/HOST ` |
202289| ` stage2 ` builds ` test ` /` std ` (not HOST targets) | ` build/HOST/stage2-std/TARGET ` |
203290| 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 ` |
205292| copy ` rustdoc ` | ` build/HOST/stage2/bin ` |
206293
207294` --stage=2 ` stops here.
208295
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-
283296## Passing stage-specific flags to ` rustc `
284297
285298` x.py ` allows you to pass stage-specific flags to ` rustc ` when bootstrapping.
286299The ` RUSTFLAGS_STAGE_0 ` , ` RUSTFLAGS_STAGE_1 ` and ` RUSTFLAGS_STAGE_2 `
287300environment variables pass the given flags when building stage 0, 1, and 2
288301artifacts respectively.
289302
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
291304the given arguments if the stage is not 0.
292305
293306## Environment Variables
0 commit comments