Skip to content

Commit cbc46e4

Browse files
committed
rewrite bootstrapping stages
1 parent 4b8d939 commit cbc46e4

File tree

1 file changed

+65
-47
lines changed

1 file changed

+65
-47
lines changed

src/building/bootstrapping.md

+65-47
Original file line numberDiff line numberDiff line change
@@ -2,72 +2,90 @@
22

33
<!-- toc -->
44

5+
[Bootstrapping][boot] is the process of using a compiler to compiler a later version
6+
of itself.
57

6-
[*Bootstrapping*][boot] is the process of using a compiler to compile itself.
7-
More accurately, it means using an older compiler to compile a newer version
8-
of the same compiler.
8+
This raises a [chicken-or-the-egg
9+
paradox](https://en.wikipedia.org/wiki/Chicken_or_the_egg): what rust compiler
10+
was used to compile the very first rust compiler? The answer is that the first
11+
compiler was not written in rust. It was [written in OCaml][ocaml-compiler]. Of
12+
course, it has long been discarded and since then the only compiler that is
13+
able to compile some version of `rustc` is a slightly earlier version of
14+
`rustc`.
915

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.
16+
For this purpose a python script `x.py` is provided at the root of the
17+
repository. `x.py` downloads a pre-compiled compiler—the stage 0 compiler—and
18+
with it compiles from the current source code a compiler—the stage 1 compiler.
19+
Additionaly, it may use the stage 1 compiler to compile from the current source
20+
code another compiler—the stage 2 compiler. Below describes this process in
21+
some detail, including the reason for a stage 2 compiler and more.
1522

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.
23+
## The stages of bootstrapping
1824

19-
## Stages of bootstrapping
25+
Each stage involves:
26+
- An existing compiler and its set of dependencies.
27+
- Targets ([objects][objects]): `std` and `rustc`.
2028

21-
Compiling `rustc` is done in stages.
29+
Note: the compiler of a stage—e.g. "the stage 1 compiler"—refers to the
30+
compiler that is compiled at that stage, not the one that already exists.
2231

23-
### Stage 0
32+
In the first stage (stage 0) the compiler is usually obtained by downloading a
33+
pre-compiled one. In following stages the compiler is usually the one that was
34+
compiled in the previous stage.
2435

25-
The stage0 compiler is usually the current _beta_ `rustc` compiler
26-
and its associated dynamic libraries,
27-
which `x.py` will download for you.
28-
(You can also configure `x.py` to use something else.)
36+
[objects]: https://en.wikipedia.org/wiki/Object_code
2937

30-
The stage0 compiler is then used only to compile `rustbuild`, `std`, and `rustc`.
31-
When compiling `rustc`, the stage0 compiler uses the freshly compiled `std`.
32-
There are two concepts at play here:
33-
a compiler (with its set of dependencies)
34-
and its 'target' or 'object' libraries (`std` and `rustc`).
35-
Both are staged, but in a staggered manner.
38+
### The stages: how each compiler is obtained
3639

37-
### Stage 1
40+
#### Stage 0: the pre-compiled compiler
3841

39-
The rustc source code is then compiled with the stage0 compiler to produce the stage1 compiler.
42+
A pre-compiled compiler and its set of dependencies are downloaded. By default,
43+
it is the current beta release. This is the stage 0 compiler.
4044

41-
### Stage 2
45+
#### Stage 1: from current code, by an earlier compiler
4246

43-
We then rebuild our stage1 compiler with itself to produce the stage2 compiler.
47+
The stage 0 compiler compiles from current code `rustbuild` and `std` and uses
48+
them to compile from current code a compiler. This is the stage 1 compiler.
4449

45-
In theory, the stage1 compiler is functionally identical to the stage2 compiler,
46-
but in practice there are subtle differences.
47-
In particular, the stage1 compiler itself was built by stage0
48-
and hence not by the source in your working directory.
49-
This means that the symbol names used in the compiler source
50-
may not match the symbol names that would have been made by the stage1 compiler,
51-
which can cause problems for dynamic libraries and tests.
50+
The stage 1 compiler is the first that is from current code. Yet, it is not
51+
entirely up-to-date, because the compiler that compiled it is of earlier code.
52+
More on this below.
5253

53-
The `stage2` compiler is the one distributed with `rustup` and all other install methods.
54-
However, it takes a very long time to build
55-
because one must first build the new compiler with an older compiler
56-
and then use that to build the new compiler with itself.
57-
For development, you usually only want the `stage1` compiler,
58-
which you can build with `./x.py build library/std`.
54+
#### Stage 2: the truly current compiler
55+
56+
By default, the stage 1 libraries are copied into stage 2, because they are
57+
expected to be identical.
58+
59+
The stage 1 compiler is used to compile from current code a compiler. This is
60+
the stage 2 compiler.
61+
62+
The stage 2 compiler is the first that is both from current code and compiled
63+
by a compiler that is of current code. The compilers and libraries obtained by
64+
`rustup` and other installation methods are all stage 2.
65+
66+
For most purposes a stage 1 compiler would suffice: `x.py build library/std`.
5967
See [Building the Compiler](./how-to-build-and-run.html#building-the-compiler).
68+
Between the stage 2 and the stage 1 compiler are subtle differences:
69+
70+
The symbol names used in the compiler source may not match the symbol names
71+
that would have been made by the stage1 compiler. This is important when using
72+
dynamic linking and due to the lack of ABI compatibility between versions. This
73+
primarily manifests when tests try to link with any of the `rustc_*` crates or
74+
use the (now deprecated) plugin infrastructure. These tests are marked with
75+
`ignore-stage1`.
76+
77+
Also, the stage 2 compiler benefits from the compile-time optimizations
78+
generated by a compiler that is of the current code.
6079

61-
### Stage 3
80+
#### Stage 3: the same-result test
6281

63-
Stage 3 is optional. To sanity check our new compiler, we
64-
can build the libraries with the stage2 compiler. The result ought
65-
to be identical to before, unless something has broken.
82+
To verify that the stage 2 libraries that were copied from stage 1 are indeed
83+
identical to those which would otherwise have been compiled in stage 2, the
84+
stage 2 compiler is used to compile them and a comparison is made.
6685

6786
### Building the stages
6887

69-
`x.py` tries to be helpful and pick the stage you most likely meant for each subcommand.
70-
These defaults are as follows:
88+
`x.py` provides a reasonable default stage for each subcommand:
7189

7290
- `check`: `--stage 0`
7391
- `doc`: `--stage 0`
@@ -77,7 +95,7 @@ These defaults are as follows:
7795
- `install`: `--stage 2`
7896
- `bench`: `--stage 2`
7997

80-
You can always override the stage by passing `--stage N` explicitly.
98+
Of course, these can be overridden by passing `--stage <number>`.
8199

82100
For more information about stages, [see below](#understanding-stages-of-bootstrap).
83101

0 commit comments

Comments
 (0)