-
Notifications
You must be signed in to change notification settings - Fork 515
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Explain stages (take N) #843
Changes from all commits
c0bd637
13772e6
0c3ec37
068bcda
caac2dc
e4d68e8
afc7c65
6db155d
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change | ||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
@@ -57,6 +57,75 @@ first 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: `x.py build library/std`. | ||||||||||||||||||
|
||||||||||||||||||
## Where do stages start and end? | ||||||||||||||||||
|
||||||||||||||||||
A common question is what exactly happens when you run `x.py build` or `x.py test`. | ||||||||||||||||||
Does `--stage 1` mean to _build_ the stage 1 artifacts or to _run_ them? | ||||||||||||||||||
In fact, it means both! | ||||||||||||||||||
|
||||||||||||||||||
<!-- TODO: label each of the cells with the name of the directory in `build` it corresponds to --> | ||||||||||||||||||
|
||||||||||||||||||
![stages](./stages.png) | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @RDambrosio016 mentioned that I should probably explain what stage 3 is and that it's not really useful except for verifying reproducible builds. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 👍 |
||||||||||||||||||
|
||||||||||||||||||
So, for example, when you run `x.py test [--stage 1]`, | ||||||||||||||||||
that means to build the compiler in row 1 and column 0, then run it on the testsuite. | ||||||||||||||||||
This corresponds to the `run-stage` diagram. | ||||||||||||||||||
However, when you run `x.py build [--stage 1]`, that means to build the compiler in | ||||||||||||||||||
row 2 and column 1. This corresponds to the `build-stage` diagram. | ||||||||||||||||||
Building any of the items in the diagram also requires first building all | ||||||||||||||||||
items with arrows pointing to it. | ||||||||||||||||||
|
||||||||||||||||||
The diagram just says `rustc` for simplicity, but this also includes all | ||||||||||||||||||
programs linked to rustc: | ||||||||||||||||||
|
||||||||||||||||||
- `rustdoc` | ||||||||||||||||||
- `rustfmt` | ||||||||||||||||||
- `clippy` | ||||||||||||||||||
- `miri` | ||||||||||||||||||
- compiler plugins | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What exactly is meant by "compiler plugins"? When I hear "compiler plugins" I think of procedural macros, but I don't think that's what's meant here. |
||||||||||||||||||
|
||||||||||||||||||
Similarly, `std` refers to the whole standard library: | ||||||||||||||||||
|
||||||||||||||||||
- `core` | ||||||||||||||||||
- `alloc` | ||||||||||||||||||
- `std` | ||||||||||||||||||
- `test` | ||||||||||||||||||
- `proc_macro` | ||||||||||||||||||
|
||||||||||||||||||
### What are `run-stage` and `build-stage`? | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I still don't feel like I fully understand what the distinction between these is. |
||||||||||||||||||
|
||||||||||||||||||
`run-stage` means that this deals with _running_ the compiler, | ||||||||||||||||||
so `--stage N` refers to the artifacts in `build/stageN`. | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same as below: I think it's clearer if you delineate what is literal text and what is filled in with some value.
Suggested change
|
||||||||||||||||||
|
||||||||||||||||||
`build-stage` means that this deals with _building_ the compiler, | ||||||||||||||||||
and it refers to `build/stageN-component`. | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's clearer if you delineate what is literal text and what is filled in with some value.
Suggested change
|
||||||||||||||||||
|
||||||||||||||||||
`build/stageN` is suitable for use with `rustup toolchain link`, | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Something like this maybe?
Suggested change
|
||||||||||||||||||
but `stageN-component` never has enough components to be usable (since it only has one). | ||||||||||||||||||
Copying these artifacts from `stage(N-1)-component` to `stageN` | ||||||||||||||||||
is called _uplifting_ the artifacts to `stageN`. | ||||||||||||||||||
|
||||||||||||||||||
### Why have `build-stage` at all? | ||||||||||||||||||
|
||||||||||||||||||
`stage0/bin/rustc` can't open an rlib from stage1-* or vice-versa. | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
They are completely separate worlds, and `build-stage` reflects those worlds quite directly. | ||||||||||||||||||
Say you want to build a custom driver and you've run | ||||||||||||||||||
`rustup toolchain link build/*/stage1`: you have to run | ||||||||||||||||||
`x.py build --stage 1 src/librustc_driver` to have it available. | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
The stage number corresponds to the "world" you have to be in to use it. | ||||||||||||||||||
If this used `run-stage` instead, you'd need `x.py build --stage 1` to build | ||||||||||||||||||
a regular program, but `x.py build --stage 2 src/librustc_driver` to build a | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||||||||||||||
custom driver. | ||||||||||||||||||
Comment on lines
+112
to
+118
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This section kind of confuses me. Since this is for relatively new contributors, maybe it would be better to not use a somewhat niche example? Or maybe if you could just make it a bit more verbose so that it's easier to follow along :) |
||||||||||||||||||
|
||||||||||||||||||
### Are there other ways to think about stages? | ||||||||||||||||||
|
||||||||||||||||||
Yes! The above explanation focuses on what `rustc` is being _referred_ to - | ||||||||||||||||||
it describes `build --stage 1 src/rustc` as `build-stage` 1 and `run-stage 2`. | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. One of these to make it consistent:
Suggested change
Suggested change
|
||||||||||||||||||
However, another way to think about it is that `--stage 1` refers to | ||||||||||||||||||
the compiler _being run_, so `build --stage 1 src/rustc` means to _run_ | ||||||||||||||||||
`stage1/rustc` on the `src/rustc` crate. This can be slightly more confusing | ||||||||||||||||||
at first, but leads to a more consistent view of 'stage'. | ||||||||||||||||||
Comment on lines
+124
to
+127
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Actually, this is much clearer to me! (Assuming that I'm understanding it properly ;) Maybe use this explanation first and put the other explanation here? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Also, I think it was moved right?
Suggested change
|
||||||||||||||||||
|
||||||||||||||||||
## Complications of bootstrapping | ||||||||||||||||||
|
||||||||||||||||||
Since the build system uses the current beta compiler to build the stage-1 | ||||||||||||||||||
|
@@ -152,7 +221,8 @@ Keep in mind this diagram is a simplification, i.e. `rustdoc` can be built at | |||||||||||||||||
different stages, the process is a bit different when passing flags such as | ||||||||||||||||||
`--keep-stage`, or if there are non-host targets. | ||||||||||||||||||
|
||||||||||||||||||
The following tables indicate the outputs of various stage actions: | ||||||||||||||||||
The following tables indicate the outputs of various stage actions | ||||||||||||||||||
(in this context, 'stage' refers to `build-stage`): | ||||||||||||||||||
|
||||||||||||||||||
| Stage 0 Action | Output | | ||||||||||||||||||
|-----------------------------------------------------------|----------------------------------------------| | ||||||||||||||||||
|
@@ -192,7 +262,7 @@ The following tables indicate the outputs of various stage actions: | |||||||||||||||||
|
||||||||||||||||||
`--stage=2` stops here. | ||||||||||||||||||
|
||||||||||||||||||
Note that the convention `x.py` uses is that: | ||||||||||||||||||
Note that the convention `x.py` uses for `build-stage` is that: | ||||||||||||||||||
- A "stage N artifact" is an artifact that is _produced_ by the stage N compiler. | ||||||||||||||||||
- The "stage (N+1) compiler" is assembled from "stage N artifacts". | ||||||||||||||||||
- A `--stage N` flag means build _with_ stage N. | ||||||||||||||||||
|
@@ -276,6 +346,8 @@ artifacts respectively. | |||||||||||||||||
Additionally, the `RUSTFLAGS_STAGE_NOT_0` variable, as its name suggests, pass | ||||||||||||||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is not from this PR, but I figure we might as well fix it now!
Suggested change
|
||||||||||||||||||
the given arguments if the stage is not 0. | ||||||||||||||||||
|
||||||||||||||||||
In this context, `STAGE` refers to `build-stage`. | ||||||||||||||||||
|
||||||||||||||||||
## Environment Variables | ||||||||||||||||||
|
||||||||||||||||||
During bootstrapping, there are a bunch of compiler-internal environment | ||||||||||||||||||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
@@ -0,0 +1,79 @@ | ||||||
\documentclass{standalone} | ||||||
|
||||||
\usepackage{tikz} | ||||||
\usetikzlibrary{arrows.meta} | ||||||
|
||||||
\begin{document} | ||||||
|
||||||
\noindent | ||||||
\begin{tikzpicture} | ||||||
|
||||||
\node[text width=5in] at (2.5, 2) { | ||||||
\noindent Arrows represent build dependencies. | ||||||
Columns are things that are linked together. | ||||||
Rows are things that can be used together to build a program. | ||||||
\\ | ||||||
|
||||||
\noindent \verb|./x.py build --stage N| builds programs in \emph{column} \verb|N| (except rustdoc - it builds rustdoc from column \verb|N - 1|).\\ | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. To get a proper en dash:
Suggested change
|
||||||
\noindent \verb|./x.py test --stage N| builds and tests everything in \emph{row} \verb|N|.\\ | ||||||
\noindent \verb|./x.py doc --stage N| generates docs with rustdoc from \emph{row} \verb|N|.\\ | ||||||
}; | ||||||
|
||||||
\draw[draw=black,fill=white,fill opacity=0.5] (-3, -0.5) rectangle ++(12, 1); | ||||||
\draw[fill=teal,fill opacity=0.5] (-3, -1.5) rectangle ++(12, 1); | ||||||
\draw[fill=olive,fill opacity=0.5] (-3, -2.5) rectangle ++(12, 1); | ||||||
\draw[fill=pink,fill opacity=0.5] (-3, -3.5) rectangle ++(12, 1); | ||||||
|
||||||
\draw[draw=black,fill=white,fill opacity=0.5] (1, 0.5) rectangle ++(2, -5); | ||||||
\draw[fill=teal,fill opacity=0.5] (3, 0.5) rectangle ++(2, -5); | ||||||
\draw[fill=olive,fill opacity=0.5] (5, 0.5) rectangle ++(2, -5); | ||||||
\draw[fill=pink,fill opacity=0.5] (7, 0.5) rectangle ++(2, -5); | ||||||
|
||||||
\node[rotate=90] at (-3.5, -1.5) {run-stage}; | ||||||
|
||||||
\node[] at (-2, 0) {stage 0}; | ||||||
\node[] at (-2, -1) {stage 1}; | ||||||
\node[] at (-2, -2) {stage 2}; | ||||||
\node[] at (-2, -3) {stage 3}; | ||||||
|
||||||
\node[] at (5, -5) {build-stage}; | ||||||
|
||||||
\node[] at (2, -4) {stage 0}; | ||||||
\node[] at (4, -4) {stage 1}; | ||||||
\node[] at (6, -4) {stage 2}; | ||||||
\node[] at (8, -4) {stage 3}; | ||||||
|
||||||
\begin{scope}[every node/.style={thick,draw,fill=white}] | ||||||
\node (s0r) at (0,0) {beta rustc}; | ||||||
\node (s0s) at (2,0) {std}; | ||||||
\node (s1r) at (2,-1) {rustc}; | ||||||
\node (s1s) at (4,-1) {std}; | ||||||
\node (s2r) at (4,-2) {rustc}; | ||||||
\node (s2s) at (6,-2) {std}; | ||||||
\node (s3r) at (6,-3) {rustc}; | ||||||
\node (s3s) at (8,-3) {std}; | ||||||
\end{scope} | ||||||
|
||||||
\begin{scope}[>={Stealth[black]}, every edge/.style={draw=black,very thick}] | ||||||
\path [->] (s0r) edge node {} (s0s); | ||||||
\path [->] (s0r) edge node {} (s1r); | ||||||
\path [->] (s0s) edge node {} (s1r); | ||||||
\path [->] (s1r) edge node {} (s1s); | ||||||
\path [->] (s1r) edge node {} (s2r); | ||||||
\path [->] (s1s) edge node {} (s2r); | ||||||
\path [->] (s2r) edge node {} (s2s); | ||||||
\path [->] (s2r) edge node {} (s3r); | ||||||
\path [->] (s2s) edge node {} (s3r); | ||||||
\path [->] (s3r) edge node {} (s3s); | ||||||
\end{scope} | ||||||
|
||||||
\node[text width=5in] at (2.5, -6) { | ||||||
\noindent \verb|build| excludes \verb|rustc| by default. | ||||||
|
||||||
Use \verb|build --stage N src/rustc| to build the \verb|rustc| in \emph{column} | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
|
||||||
\verb|N|. | ||||||
Comment on lines
+71
to
+74
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This confuses me. It sounds like it means that |
||||||
}; | ||||||
|
||||||
\end{tikzpicture} | ||||||
|
||||||
\end{document} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this TODO still valid?