Skip to content

Commit 0f69d33

Browse files
pierwilljyn514
andcommitted
Edit introduction to bootstrapping
Use paragraphs instead of bullet-points. Edits throughout for clarity. Use semantic line breaks in edited sections. Co-authored-by: Joshua Nelson <[email protected]>
1 parent 70966e5 commit 0f69d33

File tree

1 file changed

+61
-54
lines changed

1 file changed

+61
-54
lines changed

Diff for: src/building/bootstrapping.md

+61-54
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,8 @@
22

33
<!-- toc -->
44

5-
This subchapter is about the bootstrapping process.
65

7-
## What is bootstrapping? How does it work?
8-
9-
[Bootstrapping] is the process of using a compiler to compile itself.
6+
[*Bootstrapping*] is the process of using a compiler to compile itself.
107
More accurately, it means using an older compiler to compile a newer version
118
of the same compiler.
129

@@ -21,45 +18,53 @@ rustc, then uses it to compile the new compiler.
2118

2219
## Stages of bootstrapping
2320

24-
Compiling `rustc` is done in stages:
25-
26-
- **Stage 0:** the stage0 compiler is usually (you can configure `x.py` to use
27-
something else) the current _beta_ `rustc` compiler and its associated dynamic
28-
libraries (which `x.py` will download for you). This stage0 compiler is then
29-
used only to compile `rustbuild`, `std`, and `rustc`. When compiling
30-
`rustc`, this stage0 compiler uses the freshly compiled `std`.
31-
There are two concepts at play here: a compiler (with its set of dependencies)
32-
and its 'target' or 'object' libraries (`std` and `rustc`).
33-
Both are staged, but in a staggered manner.
34-
- **Stage 1:** the code in your clone (for new version) is then
35-
compiled with the stage0 compiler to produce the stage1 compiler.
36-
However, it was built with an older compiler (stage0), so to
37-
optimize the stage1 compiler we go to the next stage.
38-
- In theory, the stage1 compiler is functionally identical to the
39-
stage2 compiler, but in practice there are subtle differences. In
40-
particular, the stage1 compiler itself was built by stage0 and
41-
hence not by the source in your working directory: this means that
42-
the symbol names used in the compiler source may not match the
43-
symbol names that would have been made by the stage1 compiler. This is
44-
important when using dynamic linking and the lack of ABI compatibility
45-
between versions. This primarily manifests when tests try to link with any
46-
of the `rustc_*` crates or use the (now deprecated) plugin infrastructure.
47-
These tests are marked with `ignore-stage1`.
48-
- **Stage 2:** we rebuild our stage1 compiler with itself to produce
49-
the stage2 compiler (i.e. it builds itself) to have all the _latest
50-
optimizations_. (By default, we copy the stage1 libraries for use by
51-
the stage2 compiler, since they ought to be identical.)
52-
- _(Optional)_ **Stage 3**: to sanity check our new compiler, we
53-
can build the libraries with the stage2 compiler. The result ought
54-
to be identical to before, unless something has broken.
55-
56-
The `stage2` compiler is the one distributed with `rustup` and all other
57-
install methods. However, it takes a very long time to build because one must
58-
first build the new compiler with an older compiler and then use that to
59-
build the new compiler with itself. For development, you usually only want
60-
the `stage1` compiler: `x.py build library/std`.
61-
62-
### Default stages
21+
Compiling `rustc` is done in stages.
22+
23+
### Stage 0
24+
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.)
29+
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.
36+
37+
### Stage 1
38+
39+
The rustc source code is then compiled with the stage0 compiler to produce the stage1 compiler.
40+
41+
### Stage 2
42+
43+
We then rebuild our stage1 compiler with itself to produce the stage2 compiler.
44+
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.
52+
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`.
59+
See [Building the Compiler](/building/how-to-build-and-run.html#building-the-compiler).
60+
61+
### Stage 3
62+
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.
66+
67+
### Building the stages
6368

6469
`x.py` tries to be helpful and pick the stage you most likely meant for each subcommand.
6570
These defaults are as follows:
@@ -132,9 +137,10 @@ contribution [here][bootstrap-build].
132137
This is a detailed look into the separate bootstrap stages.
133138

134139
The convention `x.py` uses is that:
140+
135141
- A `--stage N` flag means to run the stage N compiler (`stageN/rustc`).
136142
- A "stage N artifact" is a build artifact that is _produced_ by the stage N compiler.
137-
- The "stage (N+1) compiler" is assembled from "stage N artifacts". This
143+
- The stage N+1 compiler is assembled from stage N *artifacts*. This
138144
process is called _uplifting_.
139145

140146
#### Build artifacts
@@ -174,20 +180,19 @@ Build artifacts include, but are not limited to:
174180
library/std` instead, which allows compiling programs without needing to define
175181
lang items.
176182

177-
### Building vs. Running
178-
183+
### Building vs. running
179184

180185
Note that `build --stage N compiler/rustc` **does not** build the stage N compiler:
181-
instead it builds the stage _N+1_ compiler _using_ the stage N compiler.
186+
instead it builds the stage N+1 compiler _using_ the stage N compiler.
182187

183188
In short, _stage 0 uses the stage0 compiler to create stage0 artifacts which
184189
will later be uplifted to be the stage1 compiler_.
185190

186191
In each stage, two major steps are performed:
187192

188193
1. `std` is compiled by the stage N compiler.
189-
2. That `std` is linked to programs built by the stage N compiler, including
190-
the stage N artifacts (stage (N+1) compiler).
194+
2. That `std` is linked to programs built by the stage N compiler,
195+
including the stage N artifacts (stage N+1 compiler).
191196

192197
This is somewhat intuitive if one thinks of the stage N artifacts as "just"
193198
another program we are building with the stage N compiler:
@@ -202,8 +207,6 @@ Keep in mind this diagram is a simplification, i.e. `rustdoc` can be built at
202207
different stages, the process is a bit different when passing flags such as
203208
`--keep-stage`, or if there are non-host targets.
204209

205-
The stage 2 compiler is what is shipped to end-users.
206-
207210
### Stages and `std`
208211

209212
Note that there are two `std` libraries in play here:
@@ -226,10 +229,12 @@ recompiling that `std`.
226229
`--keep-stage` simply assumes the previous compile is fine and copies those
227230
artifacts into the appropriate place, skipping the cargo invocation.
228231

229-
### Cross-compiling
232+
### Cross-compiling rustc
233+
234+
*Cross-compiling* is the process of compiling code that will run on another archicture.
235+
For instance, you might want to build an ARM version of rustc using an x86 machine.
236+
Building stage2 `std` is different when you are cross-compiling.
230237

231-
Building stage2 `std` is different depending on whether you are cross-compiling or not
232-
(see in the table how stage2 only builds non-host `std` targets).
233238
This is because `x.py` uses a trick: if `HOST` and `TARGET` are the same,
234239
it will reuse stage1 `std` for stage2! This is sound because stage1 `std`
235240
was compiled with the stage1 compiler, i.e. a compiler using the source code
@@ -239,6 +244,8 @@ to the `std` that `stage2/rustc` would compile.
239244
However, when cross-compiling, stage1 `std` will only run on the host.
240245
So the stage2 compiler has to recompile `std` for the target.
241246

247+
(See in the table how stage2 only builds non-host `std` targets).
248+
242249
### Why does only libstd use `cfg(bootstrap)`?
243250

244251
The `rustc` generated by the stage0 compiler is linked to the freshly-built

0 commit comments

Comments
 (0)