Skip to content

Commit 74d9de7

Browse files
committed
Revamp bootstrapping section
- Move most of the overview to building/bootstrapping.md - Add things besides stages to bootstrapping.md
1 parent 4228f46 commit 74d9de7

File tree

2 files changed

+88
-20
lines changed

2 files changed

+88
-20
lines changed

Diff for: src/building/bootstrapping.md

+77-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,83 @@
22

33
This subchapter is about the bootstrapping process.
44

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:
682

783
```txt
884
Building stage0 std artifacts

Diff for: src/overview.md

+11-19
Original file line numberDiff line numberDiff line change
@@ -309,25 +309,17 @@ but there are already some promising performance improvements.
309309
### Bootstrapping
310310

311311
`rustc` itself is written in Rust. So how do we compile the compiler? We use an
312-
older compiler to compile the newer compiler. This is called _bootstrapping_.
313-
314-
Bootstrapping has a lot of interesting implications. For example, it means that
315-
one of the major users of Rust is Rust, so we are constantly testing our own
316-
software ("eating our own dogfood"). Also, it means building the compiler can
317-
take a long time because one must first build the new compiler with an older
318-
compiler and then use that to build the new compiler with itself (sometimes you
319-
can get away without the full 2-stage build, but for release artifacts you need
320-
the 2-stage build).
321-
322-
Bootstrapping also has implications for when features are usable in the
323-
compiler itself. The build system uses the current beta compiler to build the
324-
stage-1 bootstrapping compiler. This means that the compiler source code can't
325-
use some features until they reach beta (because otherwise the beta compiler
326-
doesn't support them). On the other hand, for [compiler intrinsics][intrinsics]
327-
and internal features, we may be able to use them immediately because the
328-
stage-1 bootstrapping compiler will support them.
329-
330-
[intrinsics]: ./appendix/glossary.md#intrinsic
312+
older compiler to compile the newer compiler. This is called [_bootstrapping_].
313+
314+
Bootstrapping has a lot of interesting implications. For example, it means
315+
that one of the major users of Rust is the Rust compiler, so we are
316+
constantly testing our own software ("eating our own dogfood").
317+
318+
For more details on bootstrapping, see
319+
[the bootstrapping section of the guide][rustc-bootstrap].
320+
321+
[_bootstrapping_]: https://en.wikipedia.org/wiki/Bootstrapping_(compilers)
322+
[rustc-bootstrap]: building/bootstrapping.md
331323

332324
# Unresolved Questions
333325

0 commit comments

Comments
 (0)