]>
Commit | Line | Data |
---|---|---|
60c5eb7d XL |
1 | # Bootstrapping the Compiler |
2 | ||
6a06907d XL |
3 | <!-- toc --> |
4 | ||
60c5eb7d | 5 | |
3c0e092e | 6 | [*Bootstrapping*][boot] is the process of using a compiler to compile itself. |
6a06907d XL |
7 | More accurately, it means using an older compiler to compile a newer version |
8 | of the same compiler. | |
9 | ||
10 | This raises a chicken-and-egg paradox: where did the first compiler come from? | |
11 | It must have been written in a different language. In Rust's case it was | |
12 | [written in OCaml][ocaml-compiler]. However it was abandoned long ago and the | |
13 | only way to build a modern version of rustc is a slightly less modern | |
14 | version. | |
15 | ||
16 | This is exactly how `x.py` works: it downloads the current beta release of | |
17 | rustc, then uses it to compile the new compiler. | |
18 | ||
19 | ## Stages of bootstrapping | |
20 | ||
f2b60f7d FG |
21 | Compiling `rustc` is done in stages. Here's a diagram, adapted from Joshua Nelson's |
22 | [talk on bootstrapping][rustconf22-talk] at RustConf 2022, with detailed explanations below. | |
23 | ||
24 | The `A`, `B`, `C`, and `D` show the ordering of the stages of bootstrapping. | |
25 | <span style="background-color: lightblue; color: black">Blue</span> nodes are downloaded, | |
26 | <span style="background-color: yellow; color: black">yellow</span> nodes are built with the | |
27 | stage0 compiler, and | |
28 | <span style="background-color: lightgreen; color: black">green</span> nodes are built with the | |
29 | stage1 compiler. | |
30 | ||
9c376795 | 31 | [rustconf22-talk]: https://www.youtube.com/watch?v=oUIjG-y4zaA |
f2b60f7d FG |
32 | |
33 | ```mermaid | |
34 | graph TD | |
35 | s0c["stage0 compiler (1.63)"]:::downloaded -->|A| s0l("stage0 std (1.64)"):::with-s0c; | |
36 | s0c & s0l --- stepb[ ]:::empty; | |
37 | stepb -->|B| s0ca["stage0 compiler artifacts (1.64)"]:::with-s0c; | |
38 | s0ca -->|copy| s1c["stage1 compiler (1.64)"]:::with-s0c; | |
39 | s1c -->|C| s1l("stage1 std (1.64)"):::with-s1c; | |
40 | s1c & s1l --- stepd[ ]:::empty; | |
41 | stepd -->|D| s1ca["stage1 compiler artifacts (1.64)"]:::with-s1c; | |
42 | s1ca -->|copy| s2c["stage2 compiler"]:::with-s1c; | |
43 | ||
44 | classDef empty width:0px,height:0px; | |
45 | classDef downloaded fill: lightblue; | |
46 | classDef with-s0c fill: yellow; | |
47 | classDef with-s1c fill: lightgreen; | |
48 | ``` | |
3c0e092e XL |
49 | |
50 | ### Stage 0 | |
51 | ||
52 | The stage0 compiler is usually the current _beta_ `rustc` compiler | |
53 | and its associated dynamic libraries, | |
54 | which `x.py` will download for you. | |
55 | (You can also configure `x.py` to use something else.) | |
56 | ||
2b03887a | 57 | The stage0 compiler is then used only to compile `src/bootstrap`, `std`, and `rustc`. |
3c0e092e XL |
58 | When compiling `rustc`, the stage0 compiler uses the freshly compiled `std`. |
59 | There are two concepts at play here: | |
60 | a compiler (with its set of dependencies) | |
61 | and its 'target' or 'object' libraries (`std` and `rustc`). | |
62 | Both are staged, but in a staggered manner. | |
63 | ||
64 | ### Stage 1 | |
65 | ||
66 | The rustc source code is then compiled with the stage0 compiler to produce the stage1 compiler. | |
67 | ||
68 | ### Stage 2 | |
69 | ||
70 | We then rebuild our stage1 compiler with itself to produce the stage2 compiler. | |
71 | ||
72 | In theory, the stage1 compiler is functionally identical to the stage2 compiler, | |
73 | but in practice there are subtle differences. | |
74 | In particular, the stage1 compiler itself was built by stage0 | |
75 | and hence not by the source in your working directory. | |
2b03887a FG |
76 | This means that the ABI generated by the stage0 compiler may not match the ABI that would have been |
77 | made by the stage1 compiler, which can cause problems for dynamic libraries, tests, and tools using | |
78 | `rustc_private`. | |
79 | ||
80 | Note that the `proc_macro` crate avoids this issue with a C FFI layer called `proc_macro::bridge`, | |
81 | allowing it to be used with stage 1. | |
3c0e092e XL |
82 | |
83 | The `stage2` compiler is the one distributed with `rustup` and all other install methods. | |
84 | However, it takes a very long time to build | |
85 | because one must first build the new compiler with an older compiler | |
86 | and then use that to build the new compiler with itself. | |
87 | For development, you usually only want the `stage1` compiler, | |
064997fb | 88 | which you can build with `./x.py build library`. |
a2a8927a | 89 | See [Building the Compiler](./how-to-build-and-run.html#building-the-compiler). |
3c0e092e XL |
90 | |
91 | ### Stage 3 | |
92 | ||
93 | Stage 3 is optional. To sanity check our new compiler, we | |
94 | can build the libraries with the stage2 compiler. The result ought | |
95 | to be identical to before, unless something has broken. | |
96 | ||
97 | ### Building the stages | |
6a06907d XL |
98 | |
99 | `x.py` tries to be helpful and pick the stage you most likely meant for each subcommand. | |
100 | These defaults are as follows: | |
101 | ||
102 | - `check`: `--stage 0` | |
103 | - `doc`: `--stage 0` | |
104 | - `build`: `--stage 1` | |
105 | - `test`: `--stage 1` | |
106 | - `dist`: `--stage 2` | |
107 | - `install`: `--stage 2` | |
108 | - `bench`: `--stage 2` | |
109 | ||
110 | You can always override the stage by passing `--stage N` explicitly. | |
111 | ||
112 | For more information about stages, [see below](#understanding-stages-of-bootstrap). | |
113 | ||
114 | ## Complications of bootstrapping | |
115 | ||
116 | Since the build system uses the current beta compiler to build the stage-1 | |
117 | bootstrapping compiler, the compiler source code can't use some features | |
118 | until they reach beta (because otherwise the beta compiler doesn't support | |
119 | them). On the other hand, for [compiler intrinsics][intrinsics] and internal | |
120 | features, the features _have_ to be used. Additionally, the compiler makes | |
121 | heavy use of nightly features (`#![feature(...)]`). How can we resolve this | |
122 | problem? | |
123 | ||
124 | There are two methods used: | |
125 | 1. The build system sets `--cfg bootstrap` when building with `stage0`, so we | |
126 | can use `cfg(not(bootstrap))` to only use features when built with `stage1`. | |
127 | This is useful for e.g. features that were just stabilized, which require | |
128 | `#![feature(...)]` when built with `stage0`, but not for `stage1`. | |
129 | 2. The build system sets `RUSTC_BOOTSTRAP=1`. This special variable means to | |
130 | _break the stability guarantees_ of rust: Allow using `#![feature(...)]` with | |
131 | a compiler that's not nightly. This should never be used except when | |
132 | bootstrapping the compiler. | |
133 | ||
3c0e092e | 134 | [boot]: https://en.wikipedia.org/wiki/Bootstrapping_(compilers) |
6a06907d XL |
135 | [intrinsics]: ../appendix/glossary.md#intrinsic |
136 | [ocaml-compiler]: https://github.com/rust-lang/rust/tree/ef75860a0a72f79f97216f8aaa5b388d98da6480/src/boot | |
137 | ||
138 | ## Contributing to bootstrap | |
139 | ||
140 | When you use the bootstrap system, you'll call it through `x.py`. | |
141 | However, most of the code lives in `src/bootstrap`. | |
142 | `bootstrap` has a difficult problem: it is written in Rust, but yet it is run | |
5099ac24 | 143 | before the Rust compiler is built! To work around this, there are two |
6a06907d XL |
144 | components of bootstrap: the main one written in rust, and `bootstrap.py`. |
145 | `bootstrap.py` is what gets run by `x.py`. It takes care of downloading the | |
146 | `stage0` compiler, which will then build the bootstrap binary written in | |
147 | Rust. | |
148 | ||
149 | Because there are two separate codebases behind `x.py`, they need to | |
150 | be kept in sync. In particular, both `bootstrap.py` and the bootstrap binary | |
151 | parse `config.toml` and read the same command line arguments. `bootstrap.py` | |
152 | keeps these in sync by setting various environment variables, and the | |
153 | programs sometimes have to add arguments that are explicitly ignored, to be | |
154 | read by the other. | |
155 | ||
156 | ### Adding a setting to config.toml | |
157 | ||
158 | This section is a work in progress. In the meantime, you can see an example | |
159 | contribution [here][bootstrap-build]. | |
160 | ||
161 | [bootstrap-build]: https://github.com/rust-lang/rust/pull/71994 | |
162 | ||
163 | ## Understanding stages of bootstrap | |
164 | ||
165 | ### Overview | |
166 | ||
167 | This is a detailed look into the separate bootstrap stages. | |
168 | ||
169 | The convention `x.py` uses is that: | |
3c0e092e | 170 | |
6a06907d XL |
171 | - A `--stage N` flag means to run the stage N compiler (`stageN/rustc`). |
172 | - A "stage N artifact" is a build artifact that is _produced_ by the stage N compiler. | |
3c0e092e | 173 | - The stage N+1 compiler is assembled from stage N *artifacts*. This |
6a06907d XL |
174 | process is called _uplifting_. |
175 | ||
176 | #### Build artifacts | |
177 | ||
178 | Anything you can build with `x.py` is a _build artifact_. | |
179 | Build artifacts include, but are not limited to: | |
180 | ||
181 | - binaries, like `stage0-rustc/rustc-main` | |
182 | - shared objects, like `stage0-sysroot/rustlib/libstd-6fae108520cf72fe.so` | |
183 | - [rlib] files, like `stage0-sysroot/rustlib/libstd-6fae108520cf72fe.rlib` | |
184 | - HTML files generated by rustdoc, like `doc/std` | |
185 | ||
186 | [rlib]: ../serialization.md | |
187 | ||
6a06907d XL |
188 | #### Examples |
189 | ||
3c0e092e XL |
190 | - `./x.py build --stage 0` means to build with the beta `rustc`. |
191 | - `./x.py doc --stage 0` means to document using the beta `rustdoc`. | |
192 | - `./x.py test --stage 0 library/std` means to run tests on the standard library | |
6a06907d XL |
193 | without building `rustc` from source ('build with stage 0, then test the |
194 | artifacts'). If you're working on the standard library, this is normally the | |
195 | test command you want. | |
9c376795 | 196 | - `./x.py test tests/ui` means to build the stage 1 compiler and run |
6a06907d XL |
197 | `compiletest` on it. If you're working on the compiler, this is normally the |
198 | test command you want. | |
199 | ||
200 | #### Examples of what *not* to do | |
201 | ||
9c376795 FG |
202 | - `./x.py test --stage 0 tests/ui` is not useful: it runs tests on the |
203 | _beta_ compiler and doesn't build `rustc` from source. Use `test tests/ui` | |
6a06907d | 204 | instead, which builds stage 1 from source. |
3c0e092e | 205 | - `./x.py test --stage 0 compiler/rustc` builds the compiler but runs no tests: |
6a06907d XL |
206 | it's running `cargo test -p rustc`, but cargo doesn't understand Rust's |
207 | tests. You shouldn't need to use this, use `test` instead (without arguments). | |
3c0e092e XL |
208 | - `./x.py build --stage 0 compiler/rustc` builds the compiler, but does not build |
209 | libstd or even libcore. Most of the time, you'll want `./x.py build | |
064997fb | 210 | library` instead, which allows compiling programs without needing to define |
3c0e092e | 211 | lang items. |
6a06907d | 212 | |
3c0e092e | 213 | ### Building vs. running |
6a06907d XL |
214 | |
215 | Note that `build --stage N compiler/rustc` **does not** build the stage N compiler: | |
3c0e092e | 216 | instead it builds the stage N+1 compiler _using_ the stage N compiler. |
6a06907d XL |
217 | |
218 | In short, _stage 0 uses the stage0 compiler to create stage0 artifacts which | |
219 | will later be uplifted to be the stage1 compiler_. | |
220 | ||
221 | In each stage, two major steps are performed: | |
222 | ||
223 | 1. `std` is compiled by the stage N compiler. | |
3c0e092e XL |
224 | 2. That `std` is linked to programs built by the stage N compiler, |
225 | including the stage N artifacts (stage N+1 compiler). | |
6a06907d XL |
226 | |
227 | This is somewhat intuitive if one thinks of the stage N artifacts as "just" | |
228 | another program we are building with the stage N compiler: | |
229 | `build --stage N compiler/rustc` is linking the stage N artifacts to the `std` | |
230 | built by the stage N compiler. | |
60c5eb7d | 231 | |
6a06907d XL |
232 | ### Stages and `std` |
233 | ||
234 | Note that there are two `std` libraries in play here: | |
235 | 1. The library _linked_ to `stageN/rustc`, which was built by stage N-1 (stage N-1 `std`) | |
236 | 2. The library _used to compile programs_ with `stageN/rustc`, which was | |
237 | built by stage N (stage N `std`). | |
238 | ||
239 | Stage N `std` is pretty much necessary for any useful work with the stage N compiler. | |
240 | Without it, you can only compile programs with `#![no_core]` -- not terribly useful! | |
241 | ||
242 | The reason these need to be different is because they aren't necessarily ABI-compatible: | |
5e7ed085 | 243 | there could be new layout optimizations, changes to MIR, or other changes |
6a06907d XL |
244 | to Rust metadata on nightly that aren't present in beta. |
245 | ||
246 | This is also where `--keep-stage 1 library/std` comes into play. Since most | |
247 | changes to the compiler don't actually change the ABI, once you've produced a | |
248 | `std` in stage 1, you can probably just reuse it with a different compiler. | |
249 | If the ABI hasn't changed, you're good to go, no need to spend time | |
250 | recompiling that `std`. | |
251 | `--keep-stage` simply assumes the previous compile is fine and copies those | |
252 | artifacts into the appropriate place, skipping the cargo invocation. | |
253 | ||
3c0e092e XL |
254 | ### Cross-compiling rustc |
255 | ||
064997fb | 256 | *Cross-compiling* is the process of compiling code that will run on another architecture. |
3c0e092e XL |
257 | For instance, you might want to build an ARM version of rustc using an x86 machine. |
258 | Building stage2 `std` is different when you are cross-compiling. | |
6a06907d | 259 | |
6a06907d XL |
260 | This is because `x.py` uses a trick: if `HOST` and `TARGET` are the same, |
261 | it will reuse stage1 `std` for stage2! This is sound because stage1 `std` | |
262 | was compiled with the stage1 compiler, i.e. a compiler using the source code | |
263 | you currently have checked out. So it should be identical (and therefore ABI-compatible) | |
264 | to the `std` that `stage2/rustc` would compile. | |
265 | ||
266 | However, when cross-compiling, stage1 `std` will only run on the host. | |
267 | So the stage2 compiler has to recompile `std` for the target. | |
268 | ||
3c0e092e XL |
269 | (See in the table how stage2 only builds non-host `std` targets). |
270 | ||
6a06907d XL |
271 | ### Why does only libstd use `cfg(bootstrap)`? |
272 | ||
273 | The `rustc` generated by the stage0 compiler is linked to the freshly-built | |
274 | `std`, which means that for the most part only `std` needs to be cfg-gated, | |
275 | so that `rustc` can use features added to std immediately after their addition, | |
276 | without need for them to get into the downloaded beta. | |
277 | ||
278 | Note this is different from any other Rust program: stage1 `rustc` | |
279 | is built by the _beta_ compiler, but using the _master_ version of libstd! | |
280 | ||
281 | The only time `rustc` uses `cfg(bootstrap)` is when it adds internal lints | |
282 | that use diagnostic items. This happens very rarely. | |
283 | ||
284 | ### What is a 'sysroot'? | |
285 | ||
286 | When you build a project with cargo, the build artifacts for dependencies | |
287 | are normally stored in `target/debug/deps`. This only contains dependencies cargo | |
288 | knows about; in particular, it doesn't have the standard library. Where do | |
289 | `std` or `proc_macro` come from? It comes from the **sysroot**, the root | |
290 | of a number of directories where the compiler loads build artifacts at runtime. | |
291 | The sysroot doesn't just store the standard library, though - it includes | |
292 | anything that needs to be loaded at runtime. That includes (but is not limited | |
293 | to): | |
294 | ||
295 | - `libstd`/`libtest`/`libproc_macro` | |
296 | - The compiler crates themselves, when using `rustc_private`. In-tree these | |
297 | are always present; out of tree, you need to install `rustc-dev` with rustup. | |
298 | - `libLLVM.so`, the shared object file for the LLVM project. In-tree this is | |
299 | either built from source or downloaded from CI; out-of-tree, you need to | |
300 | install `llvm-tools-preview` with rustup. | |
301 | ||
302 | All the artifacts listed so far are *compiler* runtime dependencies. You can | |
303 | see them with `rustc --print sysroot`: | |
304 | ||
305 | ``` | |
306 | $ ls $(rustc --print sysroot)/lib | |
307 | libchalk_derive-0685d79833dc9b2b.so libstd-25c6acf8063a3802.so | |
308 | libLLVM-11-rust-1.50.0-nightly.so libtest-57470d2aa8f7aa83.so | |
309 | librustc_driver-4f0cc9f50e53f0ba.so libtracing_attributes-e4be92c35ab2a33b.so | |
310 | librustc_macros-5f0ec4a119c6ac86.so rustlib | |
311 | ``` | |
312 | ||
313 | There are also runtime dependencies for the standard library! These are in | |
314 | `lib/rustlib`, not `lib/` directly. | |
315 | ||
316 | ``` | |
317 | $ ls $(rustc --print sysroot)/lib/rustlib/x86_64-unknown-linux-gnu/lib | head -n 5 | |
318 | libaddr2line-6c8e02b8fedc1e5f.rlib | |
319 | libadler-9ef2480568df55af.rlib | |
320 | liballoc-9c4002b5f79ba0e1.rlib | |
321 | libcfg_if-512eb53291f6de7e.rlib | |
322 | libcompiler_builtins-ef2408da76957905.rlib | |
323 | ``` | |
324 | ||
325 | `rustlib` includes libraries like `hashbrown` and `cfg_if`, which are not part | |
326 | of the public API of the standard library, but are used to implement it. | |
327 | `rustlib` is part of the search path for linkers, but `lib` will never be part | |
328 | of the search path. | |
329 | ||
330 | #### -Z force-unstable-if-unmarked | |
331 | ||
332 | Since `rustlib` is part of the search path, it means we have to be careful | |
333 | about which crates are included in it. In particular, all crates except for | |
334 | the standard library are built with the flag `-Z force-unstable-if-unmarked`, | |
335 | which means that you have to use `#![feature(rustc_private)]` in order to | |
336 | load it (as opposed to the standard library, which is always available). | |
337 | ||
338 | The `-Z force-unstable-if-unmarked` flag has a variety of purposes to help | |
339 | enforce that the correct crates are marked as unstable. It was introduced | |
340 | primarily to allow rustc and the standard library to link to arbitrary crates | |
341 | on crates.io which do not themselves use `staged_api`. `rustc` also relies on | |
342 | this flag to mark all of its crates as unstable with the `rustc_private` | |
343 | feature so that each crate does not need to be carefully marked with | |
344 | `unstable`. | |
345 | ||
346 | This flag is automatically applied to all of `rustc` and the standard library | |
347 | by the bootstrap scripts. This is needed because the compiler and all of its | |
348 | dependencies are shipped in the sysroot to all users. | |
349 | ||
350 | This flag has the following effects: | |
351 | ||
352 | - Marks the crate as "unstable" with the `rustc_private` feature if it is not | |
353 | itself marked as stable or unstable. | |
354 | - Allows these crates to access other forced-unstable crates without any need | |
355 | for attributes. Normally a crate would need a `#![feature(rustc_private)]` | |
356 | attribute to use other unstable crates. However, that would make it | |
357 | impossible for a crate from crates.io to access its own dependencies since | |
358 | that crate won't have a `feature(rustc_private)` attribute, but *everything* | |
359 | is compiled with `-Z force-unstable-if-unmarked`. | |
360 | ||
361 | Code which does not use `-Z force-unstable-if-unmarked` should include the | |
362 | `#![feature(rustc_private)]` crate attribute to access these force-unstable | |
2b03887a | 363 | crates. This is needed for things that link `rustc`, such as `miri` or |
6a06907d XL |
364 | `clippy`. |
365 | ||
366 | You can find more discussion about sysroots in: | |
367 | - The [rustdoc PR] explaining why it uses `extern crate` for dependencies loaded from sysroot | |
368 | - [Discussions about sysroot on Zulip](https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/deps.20in.20sysroot/) | |
369 | - [Discussions about building rustdoc out of tree](https://rust-lang.zulipchat.com/#narrow/stream/182449-t-compiler.2Fhelp/topic/How.20to.20create.20an.20executable.20accessing.20.60rustc_private.60.3F) | |
370 | ||
371 | [rustdoc PR]: https://github.com/rust-lang/rust/pull/76728 | |
372 | ||
2b03887a FG |
373 | ## Passing flags to commands invoked by `bootstrap` |
374 | ||
375 | `x.py` allows you to pass stage-specific flags to `rustc` and `cargo` when bootstrapping. | |
376 | The `RUSTFLAGS_BOOTSTRAP` environment variable is passed as `RUSTFLAGS` to the bootstrap stage | |
377 | (stage0), and `RUSTFLAGS_NOT_BOOTSTRAP` is passed when building artifacts for later stages. | |
378 | `RUSTFLAGS` will work, but also affects the build of `bootstrap` itself, so it will be rare to want | |
379 | to use it. | |
380 | Finally, `MAGIC_EXTRA_RUSTFLAGS` bypasses the `cargo` cache to pass flags to rustc without | |
381 | recompiling all dependencies. | |
382 | ||
383 | `RUSTDOCFLAGS`, `RUSTDOCFLAGS_BOOTSTRAP`, and `RUSTDOCFLAGS_NOT_BOOTSTRAP` are anologous to | |
384 | `RUSTFLAGS`, but for rustdoc. | |
385 | ||
386 | `CARGOFLAGS` will pass arguments to cargo itself (e.g. `--timings`). `CARGOFLAGS_BOOTSTRAP` and | |
387 | `CARGOFLAGS_NOT_BOOTSTRAP` work analogously to `RUSTFLAGS_BOOTSTRAP`. | |
388 | ||
9c376795 | 389 | `--test-args` will pass arguments through to the test runner. For `tests/ui`, this is |
2b03887a FG |
390 | compiletest; for unit tests and doctests this is the `libtest` runner. Most test runner accept |
391 | `--help`, which you can use to find out the options accepted by the runner. | |
6a06907d | 392 | |
2b03887a FG |
393 | ## Environment Variables |
394 | ||
395 | During bootstrapping, there are a bunch of compiler-internal environment | |
396 | variables that are used. If you are trying to run an intermediate version of | |
397 | `rustc`, sometimes you may need to set some of these environment variables | |
398 | manually. Otherwise, you get an error like the following: | |
399 | ||
400 | ```text | |
401 | thread 'main' panicked at 'RUSTC_STAGE was not set: NotPresent', library/core/src/result.rs:1165:5 | |
402 | ``` | |
403 | ||
404 | If `./stageN/bin/rustc` gives an error about environment variables, that | |
405 | usually means something is quite wrong -- or you're trying to compile e.g. | |
406 | `rustc` or `std` or something that depends on environment variables. In | |
407 | the unlikely case that you actually need to invoke rustc in such a situation, | |
408 | you can tell the bootstrap shim to print all env variables by adding `-vvv` to your `x.py` command. | |
409 | ||
410 | ### Directories and artifacts generated by `bootstrap` | |
411 | ||
412 | This is an incomplete reference for the outputs generated by bootstrap: | |
60c5eb7d XL |
413 | |
414 | | Stage 0 Action | Output | | |
415 | |-----------------------------------------------------------|----------------------------------------------| | |
416 | | `beta` extracted | `build/HOST/stage0` | | |
417 | | `stage0` builds `bootstrap` | `build/bootstrap` | | |
6a06907d | 418 | | `stage0` builds `test`/`std` | `build/HOST/stage0-std/TARGET` | |
60c5eb7d XL |
419 | | copy `stage0-std` (HOST only) | `build/HOST/stage0-sysroot/lib/rustlib/HOST` | |
420 | | `stage0` builds `rustc` with `stage0-sysroot` | `build/HOST/stage0-rustc/HOST` | | |
04454e1e | 421 | | copy `stage0-rustc` (except executable) | `build/HOST/stage0-sysroot/lib/rustlib/HOST` | |
60c5eb7d XL |
422 | | build `llvm` | `build/HOST/llvm` | |
423 | | `stage0` builds `codegen` with `stage0-sysroot` | `build/HOST/stage0-codegen/HOST` | | |
6a06907d | 424 | | `stage0` builds `rustdoc`, `clippy`, `miri`, with `stage0-sysroot` | `build/HOST/stage0-tools/HOST` | |
60c5eb7d XL |
425 | |
426 | `--stage=0` stops here. | |
427 | ||
428 | | Stage 1 Action | Output | | |
429 | |-----------------------------------------------------|---------------------------------------| | |
430 | | copy (uplift) `stage0-rustc` executable to `stage1` | `build/HOST/stage1/bin` | | |
431 | | copy (uplift) `stage0-codegen` to `stage1` | `build/HOST/stage1/lib` | | |
432 | | copy (uplift) `stage0-sysroot` to `stage1` | `build/HOST/stage1/lib` | | |
6a06907d | 433 | | `stage1` builds `test`/`std` | `build/HOST/stage1-std/TARGET` | |
60c5eb7d XL |
434 | | copy `stage1-std` (HOST only) | `build/HOST/stage1/lib/rustlib/HOST` | |
435 | | `stage1` builds `rustc` | `build/HOST/stage1-rustc/HOST` | | |
436 | | copy `stage1-rustc` (except executable) | `build/HOST/stage1/lib/rustlib/HOST` | | |
437 | | `stage1` builds `codegen` | `build/HOST/stage1-codegen/HOST` | | |
438 | ||
439 | `--stage=1` stops here. | |
440 | ||
6a06907d XL |
441 | | Stage 2 Action | Output | |
442 | |--------------------------------------------------------|-----------------------------------------------------------------| | |
443 | | copy (uplift) `stage1-rustc` executable | `build/HOST/stage2/bin` | | |
444 | | copy (uplift) `stage1-sysroot` | `build/HOST/stage2/lib and build/HOST/stage2/lib/rustlib/HOST` | | |
445 | | `stage2` builds `test`/`std` (not HOST targets) | `build/HOST/stage2-std/TARGET` | | |
446 | | copy `stage2-std` (not HOST targets) | `build/HOST/stage2/lib/rustlib/TARGET` | | |
447 | | `stage2` builds `rustdoc`, `clippy`, `miri` | `build/HOST/stage2-tools/HOST` | | |
448 | | copy `rustdoc` | `build/HOST/stage2/bin` | | |
60c5eb7d XL |
449 | |
450 | `--stage=2` stops here. |