@@ -57,6 +57,8 @@ first build the new compiler with an older compiler and then use that to
5757build the new compiler with itself. For development, you usually only want
5858the ` stage1 ` compiler: ` x.py build library/std ` .
5959
60+ For more information about stages, see <#understanding-stages-of-bootstrap> below.
61+
6062## Complications of bootstrapping
6163
6264Since the build system uses the current beta compiler to build the stage-1
@@ -108,50 +110,89 @@ contribution [here][bootstrap-build].
108110
109111## Understanding stages of bootstrap
110112
111- This is a detailed look into the separate bootstrap stages. When running
112- ` x.py ` you will see output such as:
113-
114- ``` txt
115- Building stage0 std artifacts
116- Copying stage0 std from stage0
117- Building stage0 compiler artifacts
118- Copying stage0 rustc from stage0
119- Building LLVM for x86_64-apple-darwin
120- Building stage0 codegen artifacts
121- Assembling stage1 compiler
122- Building stage1 std artifacts
123- Copying stage1 std from stage1
124- Building stage1 compiler artifacts
125- Copying stage1 rustc from stage1
126- Building stage1 codegen artifacts
127- Assembling stage2 compiler
128- Uplifting stage1 std
129- Copying stage2 std from stage1
130- Generating unstable book md files
131- Building stage0 tool unstable-book-gen
132- Building stage0 tool rustbook
133- Documenting standalone
134- Building rustdoc for stage2
135- Documenting book redirect pages
136- Documenting stage2 std
137- Building rustdoc for stage1
138- Documenting stage2 whitelisted compiler
139- Documenting stage2 compiler
140- Documenting stage2 rustdoc
141- Documenting error index
142- Uplifting stage1 rustc
143- Copying stage2 rustc from stage1
144- Building stage2 tool error_index_generator
145- ```
113+ ### Overview
114+
115+ This is a detailed look into the separate bootstrap stages.
116+
117+ The convention ` x.py ` uses is that:
118+ - A ` --stage N ` flag means to run the stage N compiler (` stageN/rustc ` ).
119+ - A "stage N artifact" is an artifact that is _ produced_ by the stage N compiler.
120+ - The "stage (N+1) compiler" is assembled from "stage N artifacts". This process is called _ uplifting_ .
121+
122+ For example, ` x.py build --stage 0 ` means to build with the beta ` rustc ` , and
123+ ` test --stage 0 ` isn't really meaningful (it's not running tests on your changes,
124+ but on ` beta ` , so it always fails). Similarly, ` doc --stage 0 ` means to
125+ document using the beta ` rustdoc ` .
126+
127+ Note that this implies the stage N compiler is _ not_ the same as the compiler
128+ built by ` build --stage N compiler/rustc ` -- that's 'stage N artifacts'
129+ ('the compiler built by stage N').
130+
131+ In short, _ stage 0 uses the stage0 compiler to create stage0 artifacts which
132+ will later be uplifted to stage1_ .
133+
134+ In each stage, two major steps are performed:
135+
136+ 1 . ` std ` is compiled by the stage N compiler.
137+ 2 . That ` std ` is linked to programs built by the stage N compiler, including the stage (N+1) compiler.
138+
139+ This is somewhat intuitive if one thinks of the stage (N+1) compiler as "just"
140+ another program we are building with the stage N compiler:
141+ ` build --stage N compiler/rustc ` is linking the stage (N+1) compiler to the ` std `
142+ built by the stage N compiler.
146143
147- A deeper look into ` x.py ` 's phases can be seen here :
144+ Here is a chart of a full build using x.py :
148145
149146<img alt =" A diagram of the rustc compilation phases " src =" ../img/rustc_stages.svg " class =" center " />
150147
151148Keep in mind this diagram is a simplification, i.e. ` rustdoc ` can be built at
152149different stages, the process is a bit different when passing flags such as
153150` --keep-stage ` , or if there are non-host targets.
154151
152+ The stage 1 artifacts are what is shipped to end-users, including ` stage2/bin/rustc ` .
153+
154+ ### Stages and libstd
155+
156+ Note that there are two ` std ` libraries in play here:
157+ 1 . The library _ linked_ to ` stageN/rustc ` , which was built by stage N-1 (stage N-1 ` std ` )
158+ 2 . The library _ used to compile programs_ with ` stageN/rustc ` , which was built by stage N (stage N ` std ` ).
159+
160+ stage N ` std ` is pretty much necessary for any useful work with the compiler.
161+ Without it, you can only compile programs with ` #![no_core] ` -- not terribly useful!
162+
163+ The reason these need to be different is because they aren't necessarily ABI-compatible:
164+ there could be a new layout optimization on nightly that isn't present in ` beta ` .
165+
166+ This is also where ` --keep-stage 1 library/std ` comes into play. Since most
167+ changes to the compiler don't actually change the ABI, once you've produced a
168+ ` std ` in stage 1, you can probably just reuse it with a different compiler.
169+ If the ABI hasn't changed, you're good to go, no need to spend the time
170+ recompiling that ` std ` .
171+ ` --keep-stage ` simply assumes the previous compile is fine and copies those
172+ artifacts into the appropriate place, skipping the cargo invocation.
173+
174+ ### Cross-compiling
175+
176+ Building stage2 ` std ` is different depending on whether you are cross-compiling or not
177+ (see in the table how stage2 only builds non-host ` std ` targets).
178+ This is because ` x.py ` uses a trick: if ` HOST ` and ` TARGET ` are the same,
179+ it will reuse stage1 ` std ` for stage2! This is sound because stage1 ` std `
180+ was compiled with the stage1 compiler, i.e. a compiler using the source code
181+ you currently have checked out. So it should be identical (and therefore ABI-compatible)
182+ to the ` std ` that ` stage2/rustc ` would compile.
183+
184+ However, when cross-compiling, stage1 ` std ` will only run on the host.
185+ So the stage2 compiler has to recompile ` std ` for the target.
186+
187+ ### Why does only libstd use cfg(bootstrap)?
188+
189+ The ` rustc ` generated by the stage0 compiler is linked to the freshly-built
190+ ` std ` , which means that for the most part only ` std ` needs to be cfg-gated,
191+ so that ` rustc ` can use features added to std immediately after their addition,
192+ without need for them to get into the downloaded beta.
193+
194+ ### Directories and artifacts generated by x.py
195+
155196The following tables indicate the outputs of various stage actions:
156197
157198| Stage 0 Action | Output |
@@ -164,7 +205,7 @@ The following tables indicate the outputs of various stage actions:
164205| copy ` stage0-rustc (except executable) ` | ` build/HOST/stage0-sysroot/lib/rustlib/HOST ` |
165206| build ` llvm ` | ` build/HOST/llvm ` |
166207| ` stage0 ` builds ` codegen ` with ` stage0-sysroot ` | ` build/HOST/stage0-codegen/HOST ` |
167- | ` stage0 ` builds ` rustdoc ` with ` stage0-sysroot ` | ` build/HOST/stage0-tools/HOST ` |
208+ | ` stage0 ` builds ` rustdoc ` , ` clippy ` , ` miri ` , with ` stage0-sysroot ` | ` build/HOST/stage0-tools/HOST ` |
168209
169210` --stage=0 ` stops here.
170211
@@ -192,80 +233,6 @@ The following tables indicate the outputs of various stage actions:
192233
193234` --stage=2 ` stops here.
194235
195- Note that the convention ` x.py ` uses is that:
196- - A "stage N artifact" is an artifact that is _ produced_ by the stage N compiler.
197- - The "stage (N+1) compiler" is assembled from "stage N artifacts".
198- - A ` --stage N ` flag means build _ with_ stage N.
199-
200- In short, _ stage 0 uses the stage0 compiler to create stage0 artifacts which
201- will later be uplifted to stage1_ .
202-
203- Every time any of the main artifacts (` std ` and ` rustc ` ) are compiled, two
204- steps are performed.
205- When ` std ` is compiled by a stage N compiler, that ` std ` will be linked to
206- programs built by the stage N compiler (including ` rustc ` built later
207- on). It will also be used by the stage (N+1) compiler to link against itself.
208- This is somewhat intuitive if one thinks of the stage (N+1) compiler as "just"
209- another program we are building with the stage N compiler. In some ways, ` rustc `
210- (the binary, not the ` rustbuild ` step) could be thought of as one of the few
211- ` no_core ` binaries out there.
212-
213- So "stage0 std artifacts" are in fact the output of the downloaded stage0
214- compiler, and are going to be used for anything built by the stage0 compiler:
215- e.g. ` rustc ` artifacts. When it announces that it is "building stage1
216- std artifacts" it has moved on to the next bootstrapping phase. This pattern
217- continues in latter stages.
218-
219- Also note that building host ` std ` and target ` std ` are different based on the
220- stage (e.g. see in the table how stage2 only builds non-host ` std ` targets.
221- This is because during stage2, the host ` std ` is uplifted from the "stage 1"
222- ` std ` -- specifically, when "Building stage 1 artifacts" is announced, it is
223- later copied into stage2 as well (both the compiler's ` libdir ` and the
224- ` sysroot ` ).
225-
226- This ` std ` is pretty much necessary for any useful work with the compiler.
227- Specifically, it's used as the ` std ` for programs compiled by the newly compiled
228- compiler (so when you compile ` fn main() { } ` it is linked to the last ` std `
229- compiled with ` x.py build library/std ` ).
230-
231- The ` rustc ` generated by the stage0 compiler is linked to the freshly-built
232- ` std ` , which means that for the most part only ` std ` needs to be cfg-gated,
233- so that ` rustc ` can use featured added to std immediately after their addition,
234- without need for them to get into the downloaded beta. The ` std ` built by the
235- ` stage1/bin/rustc ` compiler, also known as "stage1 std artifacts", is not
236- necessarily ABI-compatible with that compiler.
237- That is, the ` rustc ` binary most likely could not use this ` std ` itself.
238- It is however ABI-compatible with any programs that the ` stage1/bin/rustc `
239- binary builds (including itself), so in that sense they're paired.
240-
241- This is also where ` --keep-stage 1 library/std ` comes into play. Since most
242- changes to the compiler don't actually change the ABI, once you've produced a
243- ` std ` in stage 1, you can probably just reuse it with a different compiler.
244- If the ABI hasn't changed, you're good to go, no need to spend the time
245- recompiling that ` std ` .
246- ` --keep-stage ` simply assumes the previous compile is fine and copies those
247- artifacts into the appropriate place, skipping the cargo invocation.
248-
249- The reason we first build ` std ` , then ` rustc ` , is largely just
250- because we want to minimize ` cfg(stage0) ` in the code for ` rustc ` .
251- Currently ` rustc ` is always linked against a "new" ` std ` so it doesn't
252- ever need to be concerned with differences in std; it can assume that the std is
253- as fresh as possible.
254-
255- The reason we need to build it twice is because of ABI compatibility.
256- The beta compiler has it's own ABI, and then the ` stage1/bin/rustc ` compiler
257- will produce programs/libraries with the new ABI.
258- We used to build three times, but because we assume that the ABI is constant
259- within a codebase, we presume that the libraries produced by the "stage2"
260- compiler (produced by the ` stage1/bin/rustc ` compiler) is ABI-compatible with
261- the ` stage1/bin/rustc ` compiler's produced libraries.
262- What this means is that we can skip that final compilation -- and simply use the
263- same libraries as the ` stage2/bin/rustc ` compiler uses itself for programs it
264- links against.
265-
266- This ` stage2/bin/rustc ` compiler is shipped to end-users, along with the
267- ` stage 1 {std,rustc} ` artifacts.
268-
269236## Passing stage-specific flags to ` rustc `
270237
271238` x.py ` allows you to pass stage-specific flags to ` rustc ` when bootstrapping.
0 commit comments