|
2 | 2 |
|
3 | 3 | This subchapter is about the bootstrapping process.
|
4 | 4 |
|
5 |
| -When running `x.py` you will see output such as: |
| 5 | +## What is bootstrapping? How does it work? |
| 6 | + |
| 7 | +[Bootstrapping] is the process of using a compiler to compiler itself. |
| 8 | +More accurately, it means using an older compiler to compile a newer version |
| 9 | +of the same compiler. |
| 10 | + |
| 11 | +This raises a chicken-and-egg paradox: where did the first compiler come from? |
| 12 | +It must have been written in a different language. In Rust's case it was |
| 13 | +[written in OCaml][ocaml-compiler]. However it was abandoned long ago and the |
| 14 | +only way to build a modern version of rustc is a slightly less modern |
| 15 | +version. |
| 16 | + |
| 17 | +This is exactly how `x.py` works: it downloads the current `beta` release of |
| 18 | +rustc, then uses it to compile the nightly compiler. The beta release is |
| 19 | +called `stage0` and the newly built compiler is `stage1` (or `stage0 |
| 20 | +artifacts`). To get the full benefits of the new compiler (e.g. optimizations |
| 21 | +and new features), the `stage1` compiler then compiles _itself_ again. This |
| 22 | +last compiler is called `stage2` (or `stage1 artifacts`). |
| 23 | + |
| 24 | +The `stage2` compiler is the one distributed with `rustup` and all other |
| 25 | +install methods. However, it takes a very long time to build because one must |
| 26 | +first build the new compiler with an older compiler and then use that to |
| 27 | +build the new compiler with itself. For development, you usually only want |
| 28 | +the `stage1` compiler: `x.py build --stage 1 src/libstd`. |
| 29 | + |
| 30 | +## Complications of bootstrapping |
| 31 | + |
| 32 | +Since the build system uses the current beta compiler to build the stage-1 |
| 33 | +bootstrapping compiler, the compiler source code can't use some features |
| 34 | +until they reach beta (because otherwise the beta compiler doesn't support |
| 35 | +them). On the other hand, for [compiler intrinsics][intrinsics] and internal |
| 36 | +features, the features _have_ to be used. Additionally, the compiler makes |
| 37 | +heavy use of nightly features (`#![feature(...)]`). How can we resolve this |
| 38 | +problem? |
| 39 | + |
| 40 | +There are two methods used: |
| 41 | +1. The build system sets `--cfg bootstrap` when building with `stage0`, so we |
| 42 | +can use `cfg(not(bootstrap))` to only use features when built with `stage1`. |
| 43 | +This is useful for e.g. features that were just stabilized, which require |
| 44 | +`#![feature(...)]` when built with `stage0`, but not for `stage1`. |
| 45 | +2. The build system sets `RUSTC_BOOTSTRAP=1`. This special variable means to |
| 46 | +_break the stability guarantees_ of rust: Allow using `#![feature(...)]` with |
| 47 | +a compiler that's not nightly. This should never be used except when |
| 48 | +bootstrapping the compiler. |
| 49 | + |
| 50 | +[Bootstrapping]: https://en.wikipedia.org/wiki/Bootstrapping_(compilers) |
| 51 | +[intrinsics]: ../appendix/glossary.md#intrinsic |
| 52 | +[ocaml-compiler]: https://github.com/rust-lang/rust/tree/ef75860a0a72f79f97216f8aaa5b388d98da6480/src/boot |
| 53 | + |
| 54 | +## Contributing to bootstrap |
| 55 | + |
| 56 | +When you use the bootstrap system, you'll call it through `x.py`. |
| 57 | +However, most of the code lives in `src/bootstrap`. |
| 58 | +`bootstrap` has a difficult problem: it is written in Rust, but yet it is run |
| 59 | +before the rust compiler is built! To work around this, there are two |
| 60 | +components of bootstrap: the main one written in rust, and `bootstrap.py`. |
| 61 | +`bootstrap.py` is what gets run by x.py. It takes care of downloading the |
| 62 | +`stage0` compiler, which will then build the bootstrap binary written in |
| 63 | +Rust. |
| 64 | + |
| 65 | +Because there are two separate codebases being from from `x.py`, they need to |
| 66 | +be kept in sync. In particular, both `bootstrap.py` and the bootstrap binary |
| 67 | +parse `config.toml` and read the same command line arguments. `bootstrap.py` |
| 68 | +keeps these in sync by setting various environment variables, and the |
| 69 | +programs sometimes to have add arguments that are explicitly ignored, to be |
| 70 | +read by the other. |
| 71 | + |
| 72 | +### Adding a setting to config.toml |
| 73 | + |
| 74 | +This section is a work in progress. In the meantime, you can see an example contribution [here][bootstrap-build]. |
| 75 | + |
| 76 | +[bootstrap-build]: https://github.com/rust-lang/rust/pull/71994 |
| 77 | + |
| 78 | +## Stages of bootstrap |
| 79 | + |
| 80 | +This is a detailed look into the separate bootstrap stages. When running |
| 81 | +`x.py` you will see output such as: |
6 | 82 |
|
7 | 83 | ```txt
|
8 | 84 | Building stage0 std artifacts
|
|
0 commit comments