@@ -49,28 +49,36 @@ use-jemalloc = false
49
49
50
50
### Running x.py and building a stage1 compiler
51
51
52
- One thing to keep in mind is that ` rustc ` is a _ bootstrapping_ compiler. That
53
- is, since ` rustc ` is written in Rust, we need to use an older version of the
54
- compiler to compile the newer version. In particular, the newer version of the
55
- compiler, ` libstd ` , and other tooling may use some unstable features
56
- internally. The result is the compiling ` rustc ` is done in stages.
57
-
58
- - ** Stage 0:** the stage0 compiler can be your existing
59
- (perhaps older version of)
60
- Rust compiler, the current _ beta_ compiler or you may download the binary
61
- from the internet.
62
- - ** Stage 1:** the code in your clone (for new version)
63
- is then compiled with the stage0
64
- compiler to produce the stage1 compiler.
65
- However, it was built with an older compiler (stage0),
66
- so to optimize the stage1 compiler we go to next stage.
67
- - ** Stage 2:** we rebuild our stage1 compiler with itself
68
- to produce the stage2 compiler (i.e. it builds
69
- itself) to have all the _ latest optimizations_ .
70
- - _ (Optional)_ ** Stage 3** : to sanity check of our new compiler,
71
- we can build it again
72
- with stage2 compiler which must be identical to itself,
73
- unless something has broken.
52
+ One thing to keep in mind is that ` rustc ` is a _ bootstrapping_
53
+ compiler. That is, since ` rustc ` is written in Rust, we need to use an
54
+ older version of the compiler to compile the newer version. In
55
+ particular, the newer version of the compiler, ` libstd ` , and other
56
+ tooling may use some unstable features internally. The result is that
57
+ compiling ` rustc ` is done in stages:
58
+
59
+ - ** Stage 0:** the stage0 compiler is usually the current _ beta_ compiler
60
+ (` x.py ` will download it for you); you can configure ` x.py ` to use something
61
+ else, though.
62
+ - ** Stage 1:** the code in your clone (for new version) is then
63
+ compiled with the stage0 compiler to produce the stage1 compiler.
64
+ However, it was built with an older compiler (stage0), so to
65
+ optimize the stage1 compiler we go to next stage.
66
+ - (In theory, the stage1 compiler is functionally identical to the
67
+ stage2 compiler, but in practice there are subtle differences. In
68
+ particular, the stage1 compiler itself was built by stage0 and
69
+ hence not by the source in your working directory: this means that
70
+ the symbol names used in the compiler source may not match the
71
+ symbol names that would have been made by the stage1 compiler.
72
+ This can be important when using dynamic linking (e.g., with
73
+ derives. Sometimes this means that some tests don't work when run
74
+ with stage1.)
75
+ - ** Stage 2:** we rebuild our stage1 compiler with itself to produce
76
+ the stage2 compiler (i.e. it builds itself) to have all the _ latest
77
+ optimizations_ . (By default, we copy the stage1 libraries for use by
78
+ the stage2 compiler, since they ought to be identical.)
79
+ - _ (Optional)_ ** Stage 3** : to sanity check of our new compiler, we
80
+ can build the libraries with the stage2 compiler. The result ought
81
+ to be identical to before, unless something has broken.
74
82
75
83
For hacking, often building the stage 1 compiler is enough, but for
76
84
final testing and release, the stage 2 compiler is used.
@@ -80,6 +88,8 @@ It is, in particular, very useful when you're doing some kind of
80
88
"type-based refactoring", like renaming a method, or changing the
81
89
signature of some function.
82
90
91
+ <a name =command ></a >
92
+
83
93
Once you've created a config.toml, you are now ready to run
84
94
` x.py ` . There are a lot of options here, but let's start with what is
85
95
probably the best "go to" command for building a local rust:
@@ -88,27 +98,39 @@ probably the best "go to" command for building a local rust:
88
98
> ./x.py build -i --stage 1 src/libstd
89
99
```
90
100
91
- What this command will do is the following:
101
+ This may * look* like it only builds libstd, but that is not the case.
102
+ What this command does is the following:
103
+
104
+ - Build libstd using the stage0 compiler (using incremental)
105
+ - Build librustc using the stage0 compiler (using incremental)
106
+ - This produces the stage1 compiler
107
+ - Build libstd using the stage1 compiler (cannot use incremental)
108
+
109
+ This final product (stage1 compiler + libs built using that compiler)
110
+ is what you need to build other rust programs.
92
111
93
- - Using the beta compiler (also called stage 0), it will build the
94
- standard library and rustc from the ` src ` directory. The resulting
95
- compiler is called the "stage 1" compiler.
96
- - During this build, the ` -i ` (or ` --incremental ` ) switch enables incremental
97
- compilation, so that if you later rebuild after editing things in
98
- ` src ` , you can save a bit of time.
99
- - Using this stage 1 compiler, it will build the standard library.
100
- (this is what the ` src/libstd ` ) means.
112
+ Note that the command includes the ` -i ` switch. This enables incremental
113
+ compilation. This will be used to speed up the first two steps of the process:
114
+ in particular, if you make a small change, we ought to be able to use your old
115
+ results to make producing the stage1 ** compiler** faster.
101
116
102
- This is just a subset of the full rustc build. The ** full** rustc build
103
- (what you get if you just say ` ./x.py build ` ) has quite a few more steps:
117
+ Unfortunately, incremental cannot be used to speed up making the
118
+ stage1 libraries. This is because incremental only works when you run
119
+ the * same compiler* twice in a row. In this case, we are building a
120
+ * new stage1 compiler* every time. Therefore, the old incremental
121
+ results may not apply. ** As a result, you will probably find that
122
+ building the stage1 libstd is a bottleneck for you** -- but fear not,
123
+ there is a (hacky) workaround. See [ the section on "recommended
124
+ workflows"] ( #workflow ) below.
104
125
105
- - Build stage1 rustc with stage0 compiler.
106
- - Build libstd with stage1 compiler (up to here is the same).
107
- - Build rustc from ` src ` again, this time with the stage1 compiler
108
- (this part is new).
126
+ Note that this whole command just gives you a subset of the full rustc
127
+ build. The ** full** rustc build (what you get if you just say `./x.py
128
+ build`) has quite a few more steps:
129
+
130
+ - Build librustc and rustc with the stage1 compiler.
109
131
- The resulting compiler here is called the "stage2" compiler.
110
132
- Build libstd with stage2 compiler.
111
- - Build librustdoc and a bunch of other things.
133
+ - Build librustdoc and a bunch of other things with the stage2 compiler .
112
134
113
135
<a name =toolchain ></a >
114
136
@@ -148,6 +170,66 @@ release: 1.25.0-dev
148
170
LLVM version: 4.0
149
171
```
150
172
173
+ <a name =workflow ></a >
174
+
175
+ ### Suggested workflows for faster builds of the compiler
176
+
177
+ There are two workflows that are useful for faster builders of the
178
+ compiler.
179
+
180
+ ** Check, check, and check again.** The first workflow, which is useful
181
+ when doing simple refactorings, is to run ` ./x.py check `
182
+ continuously. Here you are just checking that the compiler can
183
+ ** build** , but often that is all you need (e.g., when renaming a
184
+ method). You can then run ` ./x.py build ` when you actually need to
185
+ run tests.
186
+
187
+ In fact, it is sometimes useful to put off tests even when you are not
188
+ 100% sure the code will work. You can then keep building up
189
+ refactoring commits and only run the tests at some later time. You can
190
+ then use ` git bisect ` to track down ** precisely** which commit caused
191
+ the problem. A nice side-effect of this style is that you are left
192
+ with a fairly fine-grained set of commits at the end, all of which
193
+ build and pass tests. This often helps reviewing.
194
+
195
+ ** Incremental builds with ` --keep-stage ` .** Sometimes just checking
196
+ whether the compiler builds is not enough. A common example is that
197
+ you need to add a ` debug! ` statement to inspect the value of some
198
+ state or better understand the problem. In that case, you really need
199
+ a full build. By leveraging incremental, though, you can often get
200
+ these builds to complete very fast (e.g., around 30 seconds): the only
201
+ catch is this requires a bit of fudging and may produce compilers that
202
+ don't work (but that is easily detected and fixed).
203
+
204
+ The sequence of commands you want is as follows:
205
+
206
+ - Initial build: ` ./x.py build -i --stage 1 src/libstd `
207
+ - As [ documented above] ( #command ) , this will build a functional
208
+ stage1 compiler
209
+ - Subsequent builds: ` ./x.py build -i --stage 1 src/libstd --keep-stage 1 `
210
+ - Note that we added the ` --keep-stage 1 ` flag here
211
+
212
+ The effect of ` --keep-stage 1 ` is that we just * assume* that the old
213
+ standard library can be re-used. If you are editing the compiler, this
214
+ is almost always true: you haven't changed the standard library, after
215
+ all. But sometimes, it's not true: for example, if you are editing
216
+ the "metadata" part of the compiler, which controls how the compiler
217
+ encodes types and other states into the ` rlib ` files, or if you are
218
+ editing things that wind up in the metadata (such as the definition of
219
+ the MIR).
220
+
221
+ ** The TL;DR is that you might get weird behavior from a compile when
222
+ using ` --keep-stage 1 ` ** -- for example, strange
223
+ [ ICEs] ( appendix/glossary.html ) or other panics. In that case, you
224
+ should simply remove the ` --keep-stage 1 ` from the command and
225
+ rebuild. That ought to fix the problem.
226
+
227
+ You can also use ` --keep-stage 1 ` when running tests. Something like
228
+ this:
229
+
230
+ - Initial test run: ` ./x.py test -i --stage 1 src/test/ui `
231
+ - Subsequent test run: ` ./x.py test -i --stage 1 src/test/ui --keep-stage 1 `
232
+
151
233
### Other x.py commands
152
234
153
235
Here are a few other useful x.py commands. We'll cover some of them in detail
0 commit comments