Skip to content

Commit

Permalink
Fix and clean up the terminology for stages
Browse files Browse the repository at this point in the history
- Use 'stage0 rustc' to mean `stage0-rustc`
- Use 'bootstrap' to mean `build/$target/stage0` (i.e. the beta compiler)
- Mention that 'ignore-stage1' means 'ignore programs linked to stage1',
not built by it.
  • Loading branch information
jyn514 committed Jul 22, 2020
1 parent 7f71c09 commit 3ee7880
Show file tree
Hide file tree
Showing 2 changed files with 41 additions and 32 deletions.
41 changes: 41 additions & 0 deletions src/building/bootstrapping.md
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,47 @@ contribution [here][bootstrap-build].

## Stages of bootstrap

Like most other bootstrapping compilers, `rustc` is compiled in stages.
_Unlike_ most other compilers, where `stage0` refers to the bootstrap compiler,
`stage0` refers to the first compiler built by bootstrap. So the following command:

```sh
x.py build --stage 0 src/rustc
```

will actually perform a full build of rustc. Confusingly, the `build/$target/stageN` directories are named after the compiler they are *used to build*, not the commands you need to build them.

- **Stage 0:** The stage0 compiler is built by the bootstrap compiler.
The bootstrap compiler is usually (you can configure `x.py` to use
something else) the current _beta_ `rustc` compiler and its associated dynamic
libraries (which `x.py` will download for you). This bootstrap compiler is then
used to compile `rustbuild`, `std`, and `rustc` (plus a few other tools, like `tidy`). When compiling
`rustc`, this bootstrap compiler uses the freshly compiled `std`.
There are two concepts at play here: a compiler (with its set of dependencies)
and its 'target' or 'object' libraries (`std` and `rustc`).
Both are staged, but in a staggered manner.
The `stage0` standard library is the one _linked_ to `stage0` rustc
(allowing you to `use std::vec::Vec` from within the compiler itself),
while `stage1 libstd` is the library _built_ by stage1. `libstd` also include `libcore`,
so without it there are very few programs that rustc can compile.

- **Stage 1:** In theory, the stage0 compiler is functionally identical to the
stage1 compiler, but in practice there are subtle differences. In
particular, the stage0 compiler was built by bootstrap and
hence not by the source in your working directory: this means that
the symbol names used in the compiler source may not match the
symbol names that would have been made by the stage1 compiler. This is
important when using dynamic linking because Rust does not have ABI compatibility
between versions. This primarily manifests when tests try to link with any
of the `rustc_*` crates or use the (now deprecated) plugin infrastructure.
These tests are marked with `ignore-stage1`. The `stage1` is because
these plugins *link* to the stage1 compiler, even though they are being
*built* by stage0. Rebuilding again also gives us the benefit of the latest optimizations (i.e. those added since the beta fork).

- _(Optional)_ **Stage 2**: to sanity check our new compiler, we
can build the libraries with the stage1 compiler. The result ought
to be identical to before, unless something has broken.

This is a detailed look into the separate bootstrap stages. When running
`x.py` you will see output such as:

Expand Down
32 changes: 0 additions & 32 deletions src/building/how-to-build-and-run.md
Original file line number Diff line number Diff line change
Expand Up @@ -109,38 +109,6 @@ to build it, such as `libstd` and other tooling, may use some unstable features
internally, requiring a specific version which understands these unstable
features.

The result is that compiling `rustc` is done in stages:

- **Stage 0:** the stage0 compiler is usually (you can configure `x.py` to use
something else) the current _beta_ `rustc` compiler and its associated dynamic
libraries (which `x.py` will download for you). This stage0 compiler is then
used only to compile `rustbuild`, `std`, and `rustc`. When compiling
`rustc`, this stage0 compiler uses the freshly compiled `std`.
There are two concepts at play here: a compiler (with its set of dependencies)
and its 'target' or 'object' libraries (`std` and `rustc`).
Both are staged, but in a staggered manner.
- **Stage 1:** the code in your clone (for new version) is then
compiled with the stage0 compiler to produce the stage1 compiler.
However, it was built with an older compiler (stage0), so to
optimize the stage1 compiler we go to next the stage.
- In theory, the stage1 compiler is functionally identical to the
stage2 compiler, but in practice there are subtle differences. In
particular, the stage1 compiler itself was built by stage0 and
hence not by the source in your working directory: this means that
the symbol names used in the compiler source may not match the
symbol names that would have been made by the stage1 compiler. This is
important when using dynamic linking and the lack of ABI compatibility
between versions. This primarily manifests when tests try to link with any
of the `rustc_*` crates or use the (now deprecated) plugin infrastructure.
These tests are marked with `ignore-stage1`.
- **Stage 2:** we rebuild our stage1 compiler with itself to produce
the stage2 compiler (i.e. it builds itself) to have all the _latest
optimizations_. (By default, we copy the stage1 libraries for use by
the stage2 compiler, since they ought to be identical.)
- _(Optional)_ **Stage 3**: to sanity check our new compiler, we
can build the libraries with the stage2 compiler. The result ought
to be identical to before, unless something has broken.

To read more about the bootstrap process, [read this chapter][bootstrap].

[bootstrap]: ./bootstrapping.md
Expand Down

0 comments on commit 3ee7880

Please sign in to comment.