update dev guidelines
Signed-off-by: onur-ozkan <work@onurozkan.dev>
This commit is contained in:
parent
19a333ad0f
commit
09eb3b3f78
|
|
@ -45,13 +45,13 @@ compiler.
|
||||||
|
|
||||||
```mermaid
|
```mermaid
|
||||||
graph TD
|
graph TD
|
||||||
s0c["stage0 compiler (1.63)"]:::downloaded -->|A| s0l("stage0 std (1.64)"):::with-s0c;
|
s0c["stage0 compiler (1.86.0-beta.1)"]:::downloaded -->|A| s0l("stage0 std (1.86.0-beta.1)"):::downloaded;
|
||||||
s0c & s0l --- stepb[ ]:::empty;
|
s0c & s0l --- stepb[ ]:::empty;
|
||||||
stepb -->|B| s0ca["stage0 compiler artifacts (1.64)"]:::with-s0c;
|
stepb -->|B| s0ca["stage0 compiler artifacts (1.87.0-dev)"]:::with-s0c;
|
||||||
s0ca -->|copy| s1c["stage1 compiler (1.64)"]:::with-s0c;
|
s0ca -->|copy| s1c["stage1 compiler (1.87.0-dev)"]:::with-s0c;
|
||||||
s1c -->|C| s1l("stage1 std (1.64)"):::with-s1c;
|
s1c -->|C| s1l("stage1 std (1.87.0-dev)"):::with-s1c;
|
||||||
s1c & s1l --- stepd[ ]:::empty;
|
s1c & s1l --- stepd[ ]:::empty;
|
||||||
stepd -->|D| s1ca["stage1 compiler artifacts (1.64)"]:::with-s1c;
|
stepd -->|D| s1ca["stage1 compiler artifacts (1.87.0-dev)"]:::with-s1c;
|
||||||
s1ca -->|copy| s2c["stage2 compiler"]:::with-s1c;
|
s1ca -->|copy| s2c["stage2 compiler"]:::with-s1c;
|
||||||
|
|
||||||
classDef empty width:0px,height:0px;
|
classDef empty width:0px,height:0px;
|
||||||
|
|
@ -62,19 +62,22 @@ graph TD
|
||||||
|
|
||||||
### Stage 0: the pre-compiled compiler
|
### Stage 0: the pre-compiled compiler
|
||||||
|
|
||||||
The stage0 compiler is usually the current _beta_ `rustc` compiler and its
|
The stage0 compiler is by default the very recent _beta_ `rustc` compiler and its
|
||||||
associated dynamic libraries, which `./x.py` will download for you. (You can
|
associated dynamic libraries, which `./x.py` will download for you. (You can
|
||||||
also configure `./x.py` to use something else.)
|
also configure `./x.py` to change stage0 to something else.)
|
||||||
|
|
||||||
The stage0 compiler is then used only to compile [`src/bootstrap`],
|
The stage0 compiler is then used only to compile [`src/bootstrap`] and [`compiler/rustc`].
|
||||||
[`library/std`], and [`compiler/rustc`]. When assembling the libraries and
|
When assembling the libraries and binaries that will become the stage1 `rustc` compiler,
|
||||||
binaries that will become the stage1 `rustc` compiler, the freshly compiled
|
the freshly compiled `rustc` and beta `std` are used.
|
||||||
`std` and `rustc` are used. There are two concepts at play here: a compiler
|
|
||||||
(with its set of dependencies) and its 'target' or 'object' libraries (`std` and
|
Note that to build the stage1 compiler we use the precompiled beta compiler and beta std from stage0.
|
||||||
`rustc`). Both are staged, but in a staggered manner.
|
Therefore, to use a compiler with a std that is freshly built from the tree, you need to build the
|
||||||
|
stage2 compiler.
|
||||||
|
|
||||||
|
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.
|
||||||
|
|
||||||
[`compiler/rustc`]: https://github.com/rust-lang/rust/tree/master/compiler/rustc
|
[`compiler/rustc`]: https://github.com/rust-lang/rust/tree/master/compiler/rustc
|
||||||
[`library/std`]: https://github.com/rust-lang/rust/tree/master/library/std
|
|
||||||
[`src/bootstrap`]: https://github.com/rust-lang/rust/tree/master/src/bootstrap
|
[`src/bootstrap`]: https://github.com/rust-lang/rust/tree/master/src/bootstrap
|
||||||
|
|
||||||
### Stage 1: from current code, by an earlier compiler
|
### Stage 1: from current code, by an earlier compiler
|
||||||
|
|
@ -84,16 +87,14 @@ The rustc source code is then compiled with the `stage0` compiler to produce the
|
||||||
|
|
||||||
### Stage 2: the truly current compiler
|
### Stage 2: the truly current compiler
|
||||||
|
|
||||||
We then rebuild our `stage1` compiler with itself to produce the `stage2`
|
We then rebuild our `stage1` compiler with in-tree std to produce the `stage2`
|
||||||
compiler.
|
compiler.
|
||||||
|
|
||||||
In theory, the `stage1` compiler is functionally identical to the `stage2`
|
The `stage1` compiler itself was built by precompiled `stage0` compiler and std
|
||||||
compiler, but in practice there are subtle differences. In particular, the
|
and hence not by the source in your working directory. This means that the ABI
|
||||||
`stage1` compiler itself was built by `stage0` and hence not by the source in
|
generated by the `stage0` compiler may not match the ABI that would have been made
|
||||||
your working directory. This means that the ABI generated by the `stage0`
|
by the `stage1` compiler, which can cause problems for dynamic libraries, tests
|
||||||
compiler may not match the ABI that would have been made by the `stage1`
|
and tools using `rustc_private`.
|
||||||
compiler, which can cause problems for dynamic libraries, tests, and tools using
|
|
||||||
`rustc_private`.
|
|
||||||
|
|
||||||
Note that the `proc_macro` crate avoids this issue with a `C` FFI layer called
|
Note that the `proc_macro` crate avoids this issue with a `C` FFI layer called
|
||||||
`proc_macro::bridge`, allowing it to be used with `stage1`.
|
`proc_macro::bridge`, allowing it to be used with `stage1`.
|
||||||
|
|
@ -101,9 +102,10 @@ Note that the `proc_macro` crate avoids this issue with a `C` FFI layer called
|
||||||
The `stage2` compiler is the one distributed with `rustup` and all other install
|
The `stage2` compiler is the one distributed with `rustup` and all other install
|
||||||
methods. However, it takes a very long time to build because one must first
|
methods. However, it takes a very long time to build because one must first
|
||||||
build the new compiler with an older compiler and then use that to build the new
|
build the new compiler with an older compiler and then use that to build the new
|
||||||
compiler with itself. For development, you usually only want the `stage1`
|
compiler with itself.
|
||||||
compiler, which you can build with `./x build library`. See [Building the
|
|
||||||
compiler](../how-to-build-and-run.html#building-the-compiler).
|
For development, you usually only want to use `--stage 1` flag to build things.
|
||||||
|
See [Building the compiler](../how-to-build-and-run.html#building-the-compiler).
|
||||||
|
|
||||||
### Stage 3: the same-result test
|
### Stage 3: the same-result test
|
||||||
|
|
||||||
|
|
@ -114,10 +116,11 @@ something has broken.
|
||||||
### Building the stages
|
### Building the stages
|
||||||
|
|
||||||
The script [`./x`] tries to be helpful and pick the stage you most likely meant
|
The script [`./x`] tries to be helpful and pick the stage you most likely meant
|
||||||
for each subcommand. These defaults are as follows:
|
for each subcommand. Here are some `x` commands with their default stages:
|
||||||
|
|
||||||
- `check`: `--stage 0`
|
- `check`: `--stage 1`
|
||||||
- `doc`: `--stage 0`
|
- `clippy`: `--stage 1`
|
||||||
|
- `doc`: `--stage 1`
|
||||||
- `build`: `--stage 1`
|
- `build`: `--stage 1`
|
||||||
- `test`: `--stage 1`
|
- `test`: `--stage 1`
|
||||||
- `dist`: `--stage 2`
|
- `dist`: `--stage 2`
|
||||||
|
|
@ -208,9 +211,6 @@ include, but are not limited to:
|
||||||
|
|
||||||
### Building vs. running
|
### Building vs. running
|
||||||
|
|
||||||
Note that `build --stage N compiler/rustc` **does not** build the stage N
|
|
||||||
compiler: instead it builds the stage N+1 compiler _using_ the stage N compiler.
|
|
||||||
|
|
||||||
In short, _stage 0 uses the `stage0` compiler to create `stage0` artifacts which
|
In short, _stage 0 uses the `stage0` compiler to create `stage0` artifacts which
|
||||||
will later be uplifted to be the stage1 compiler_.
|
will later be uplifted to be the stage1 compiler_.
|
||||||
|
|
||||||
|
|
@ -268,23 +268,6 @@ However, when cross-compiling, `stage1` `std` will only run on the host. So the
|
||||||
|
|
||||||
(See in the table how `stage2` only builds non-host `std` targets).
|
(See in the table how `stage2` only builds non-host `std` targets).
|
||||||
|
|
||||||
### Why does only libstd use `cfg(bootstrap)`?
|
|
||||||
|
|
||||||
For docs on `cfg(bootstrap)` itself, see [Complications of
|
|
||||||
Bootstrapping](#complications-of-bootstrapping).
|
|
||||||
|
|
||||||
The `rustc` generated by the `stage0` compiler is linked to the freshly-built
|
|
||||||
`std`, which means that for the most part only `std` needs to be `cfg`-gated, so
|
|
||||||
that `rustc` can use features added to `std` immediately after their addition,
|
|
||||||
without need for them to get into the downloaded `beta` compiler.
|
|
||||||
|
|
||||||
Note this is different from any other Rust program: `stage1` `rustc` is built by
|
|
||||||
the _beta_ compiler, but using the _master_ version of `libstd`!
|
|
||||||
|
|
||||||
The only time `rustc` uses `cfg(bootstrap)` is when it adds internal lints that
|
|
||||||
use diagnostic items, or when it uses unstable library features that were
|
|
||||||
recently changed.
|
|
||||||
|
|
||||||
### What is a 'sysroot'?
|
### What is a 'sysroot'?
|
||||||
|
|
||||||
When you build a project with `cargo`, the build artifacts for dependencies are
|
When you build a project with `cargo`, the build artifacts for dependencies are
|
||||||
|
|
@ -459,7 +442,6 @@ compiler itself uses to run. These aren't actually used by artifacts the new
|
||||||
compiler generates. This step also copies the `rustc` and `rustdoc` binaries we
|
compiler generates. This step also copies the `rustc` and `rustdoc` binaries we
|
||||||
generated into `build/$HOST/stage/bin`.
|
generated into `build/$HOST/stage/bin`.
|
||||||
|
|
||||||
The `stage1/bin/rustc` is a fully functional compiler, but it doesn't yet have
|
The `stage1/bin/rustc` is a fully functional compiler built with the beta compiler and std.
|
||||||
any libraries to link built binaries or libraries to. The next 3 steps will
|
To use a compiler built entirely from source with the in-tree compiler and std, you need to build
|
||||||
provide those libraries for it; they are mostly equivalent to constructing the
|
the stage2 compiler, which is compiled using the stage1 compiler and std.
|
||||||
`stage1/bin` compiler so we don't go through them individually here.
|
|
||||||
|
|
|
||||||
|
|
@ -217,7 +217,6 @@ probably the best "go to" command for building a local compiler:
|
||||||
This may *look* like it only builds the standard library, but that is not the case.
|
This may *look* like it only builds the standard library, but that is not the case.
|
||||||
What this command does is the following:
|
What this command does is the following:
|
||||||
|
|
||||||
- Build `std` using the stage0 compiler
|
|
||||||
- Build `rustc` using the stage0 compiler
|
- Build `rustc` using the stage0 compiler
|
||||||
- This produces the stage1 compiler
|
- This produces the stage1 compiler
|
||||||
- Build `std` using the stage1 compiler
|
- Build `std` using the stage1 compiler
|
||||||
|
|
@ -241,8 +240,7 @@ build. The **full** `rustc` build (what you get with `./x build
|
||||||
--stage 2 compiler/rustc`) has quite a few more steps:
|
--stage 2 compiler/rustc`) has quite a few more steps:
|
||||||
|
|
||||||
- Build `rustc` with the stage1 compiler.
|
- Build `rustc` with the stage1 compiler.
|
||||||
- The resulting compiler here is called the "stage2" compiler.
|
- The resulting compiler here is called the "stage2" compiler, which uses stage1 std from the previous command.
|
||||||
- Build `std` with stage2 compiler.
|
|
||||||
- Build `librustdoc` and a bunch of other things with the stage2 compiler.
|
- Build `librustdoc` and a bunch of other things with the stage2 compiler.
|
||||||
|
|
||||||
You almost never need to do this.
|
You almost never need to do this.
|
||||||
|
|
@ -250,14 +248,14 @@ You almost never need to do this.
|
||||||
### Build specific components
|
### Build specific components
|
||||||
|
|
||||||
If you are working on the standard library, you probably don't need to build
|
If you are working on the standard library, you probably don't need to build
|
||||||
the compiler unless you are planning to use a recently added nightly feature.
|
every other default component. Instead, you can build a specific component by
|
||||||
Instead, you can just build using the bootstrap compiler.
|
providing its name, like this:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
./x build --stage 0 library
|
./x build --stage 1 library
|
||||||
```
|
```
|
||||||
|
|
||||||
If you choose the `library` profile when running `x setup`, you can omit `--stage 0` (it's the
|
If you choose the `library` profile when running `x setup`, you can omit `--stage 1` (it's the
|
||||||
default).
|
default).
|
||||||
|
|
||||||
## Creating a rustup toolchain
|
## Creating a rustup toolchain
|
||||||
|
|
@ -271,7 +269,7 @@ you will likely need to build at some point; for example, if you want
|
||||||
to run the entire test suite).
|
to run the entire test suite).
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
rustup toolchain link stage0 build/host/stage0-sysroot # beta compiler + stage0 std
|
rustup toolchain link stage0 build/host/stage0-sysroot # beta compiler + beta std
|
||||||
rustup toolchain link stage1 build/host/stage1
|
rustup toolchain link stage1 build/host/stage1
|
||||||
rustup toolchain link stage2 build/host/stage2
|
rustup toolchain link stage2 build/host/stage2
|
||||||
```
|
```
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ kinds of builds (sets of jobs).
|
||||||
After each push to a pull request, a set of `pr` jobs are executed. Currently,
|
After each push to a pull request, a set of `pr` jobs are executed. Currently,
|
||||||
these execute the `x86_64-gnu-llvm-X`, `x86_64-gnu-tools`, `mingw-check-1`, `mingw-check-2`
|
these execute the `x86_64-gnu-llvm-X`, `x86_64-gnu-tools`, `mingw-check-1`, `mingw-check-2`
|
||||||
and `mingw-check-tidy` jobs, all running on Linux. These execute a relatively short
|
and `mingw-check-tidy` jobs, all running on Linux. These execute a relatively short
|
||||||
(~30 minutes) and lightweight test suite that should catch common issues. More
|
(~40 minutes) and lightweight test suite that should catch common issues. More
|
||||||
specifically, they run a set of lints, they try to perform a cross-compile check
|
specifically, they run a set of lints, they try to perform a cross-compile check
|
||||||
build to Windows mingw (without producing any artifacts) and they test the
|
build to Windows mingw (without producing any artifacts) and they test the
|
||||||
compiler using a *system* version of LLVM. Unfortunately, it would take too many
|
compiler using a *system* version of LLVM. Unfortunately, it would take too many
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue