1
1
//! Implementation of compiling the compiler and standard library, in "check"-based modes.
2
2
3
+ use build_helper:: exit;
4
+
3
5
use crate :: core:: build_steps:: compile:: {
4
6
add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo, std_crates_for_run_make,
5
7
} ;
@@ -9,10 +11,12 @@ use crate::core::builder::{
9
11
} ;
10
12
use crate :: core:: config:: TargetSelection ;
11
13
use crate :: utils:: build_stamp:: { self , BuildStamp } ;
12
- use crate :: { Mode , Subcommand } ;
14
+ use crate :: { Compiler , Mode , Subcommand } ;
13
15
14
16
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
15
17
pub struct Std {
18
+ /// Compiler that will check this std.
19
+ pub build_compiler : Compiler ,
16
20
pub target : TargetSelection ,
17
21
/// Whether to build only a subset of crates.
18
22
///
@@ -25,8 +29,8 @@ pub struct Std {
25
29
impl Std {
26
30
const CRATE_OR_DEPS : & [ & str ] = & [ "sysroot" , "coretests" , "alloctests" ] ;
27
31
28
- pub fn new ( target : TargetSelection ) -> Self {
29
- Self { target, crates : vec ! [ ] }
32
+ pub fn new ( build_compiler : Compiler , target : TargetSelection ) -> Self {
33
+ Self { build_compiler , target, crates : vec ! [ ] }
30
34
}
31
35
}
32
36
@@ -45,7 +49,11 @@ impl Step for Std {
45
49
46
50
fn make_run ( run : RunConfig < ' _ > ) {
47
51
let crates = std_crates_for_run_make ( & run) ;
48
- run. builder . ensure ( Std { target : run. target , crates } ) ;
52
+ run. builder . ensure ( Std {
53
+ build_compiler : run. builder . compiler ( run. builder . top_stage , run. target ) ,
54
+ target : run. target ,
55
+ crates,
56
+ } ) ;
49
57
}
50
58
51
59
fn run ( self , builder : & Builder < ' _ > ) {
@@ -56,9 +64,9 @@ impl Step for Std {
56
64
return ;
57
65
}
58
66
59
- let stage = builder. top_stage ;
67
+ let build_compiler = self . build_compiler ;
68
+ let stage = build_compiler. stage ;
60
69
let target = self . target ;
61
- let build_compiler = builder. compiler ( stage, builder. config . host_target ) ;
62
70
63
71
let mut cargo = builder:: Cargo :: new (
64
72
builder,
@@ -69,7 +77,7 @@ impl Step for Std {
69
77
Kind :: Check ,
70
78
) ;
71
79
72
- std_cargo ( builder, target, build_compiler . stage , & mut cargo) ;
80
+ std_cargo ( builder, target, stage, & mut cargo) ;
73
81
if matches ! ( builder. config. cmd, Subcommand :: Fix ) {
74
82
// By default, cargo tries to fix all targets. Tell it not to fix tests until we've added `test` to the sysroot.
75
83
cargo. arg ( "--lib" ) ;
@@ -126,12 +134,21 @@ impl Step for Std {
126
134
}
127
135
128
136
fn metadata ( & self ) -> Option < StepMetadata > {
129
- Some ( StepMetadata :: check ( "std" , self . target ) )
137
+ Some ( StepMetadata :: check ( "std" , self . target ) . built_by ( self . build_compiler ) )
130
138
}
131
139
}
132
140
141
+ fn default_compiler_for_checking_rustc ( builder : & Builder < ' _ > ) -> Compiler {
142
+ // When checking the stage N compiler, we want to do it with the stage N-1 compiler,
143
+ builder. compiler ( builder. top_stage - 1 , builder. config . host_target )
144
+ }
145
+
146
+ /// Checks rustc using `build_compiler` and copies the built
147
+ /// .rmeta files into the sysroot of `build_copoiler`.
133
148
#[ derive( Debug , Clone , PartialEq , Eq , Hash ) ]
134
149
pub struct Rustc {
150
+ /// Compiler that will check this rustc.
151
+ pub build_compiler : Compiler ,
135
152
pub target : TargetSelection ,
136
153
/// Whether to build only a subset of crates.
137
154
///
@@ -142,13 +159,13 @@ pub struct Rustc {
142
159
}
143
160
144
161
impl Rustc {
145
- pub fn new ( target : TargetSelection , builder : & Builder < ' _ > ) -> Self {
162
+ pub fn new ( builder : & Builder < ' _ > , build_compiler : Compiler , target : TargetSelection ) -> Self {
146
163
let crates = builder
147
164
. in_tree_crates ( "rustc-main" , Some ( target) )
148
165
. into_iter ( )
149
166
. map ( |krate| krate. name . to_string ( ) )
150
167
. collect ( ) ;
151
- Self { target, crates }
168
+ Self { build_compiler , target, crates }
152
169
}
153
170
}
154
171
@@ -163,40 +180,46 @@ impl Step for Rustc {
163
180
164
181
fn make_run ( run : RunConfig < ' _ > ) {
165
182
let crates = run. make_run_crates ( Alias :: Compiler ) ;
166
- run. builder . ensure ( Rustc { target : run. target , crates } ) ;
183
+ run. builder . ensure ( Rustc {
184
+ target : run. target ,
185
+ build_compiler : default_compiler_for_checking_rustc ( run. builder ) ,
186
+ crates,
187
+ } ) ;
167
188
}
168
189
169
- /// Builds the compiler.
190
+ /// Check the compiler.
170
191
///
171
- /// This will build the compiler for a particular stage of the build using
192
+ /// This will check the compiler for a particular stage of the build using
172
193
/// the `compiler` targeting the `target` architecture. The artifacts
173
194
/// created will also be linked into the sysroot directory.
174
195
fn run ( self , builder : & Builder < ' _ > ) {
175
- let compiler = builder. compiler ( builder. top_stage , builder. config . host_target ) ;
196
+ if builder. top_stage < 2 && builder. config . host_target != self . target {
197
+ eprintln ! ( "Cannot do a cross-compilation check on stage 1, use stage 2" ) ;
198
+ exit ! ( 1 ) ;
199
+ }
200
+
201
+ let build_compiler = self . build_compiler ;
176
202
let target = self . target ;
177
203
178
- if compiler. stage != 0 {
179
- // If we're not in stage 0, then we won't have a std from the beta
180
- // compiler around. That means we need to make sure there's one in
181
- // the sysroot for the compiler to find. Otherwise, we're going to
182
- // fail when building crates that need to generate code (e.g., build
183
- // scripts and their dependencies).
184
- builder. std ( compiler, compiler. host ) ;
185
- builder. std ( compiler, target) ;
186
- } else {
187
- builder. ensure ( Std :: new ( target) ) ;
188
- }
204
+ // Build host std for compiling build scripts
205
+ builder. std ( build_compiler, build_compiler. host ) ;
206
+
207
+ // Build target std so that the checked rustc can link to it during the check
208
+ // FIXME: maybe we can a way to only do a check of std here?
209
+ // But for that we would have to copy the stdlib rmetas to the sysroot of the build
210
+ // compiler, which conflicts with std rlibs, if we also build std.
211
+ builder. std ( build_compiler, target) ;
189
212
190
213
let mut cargo = builder:: Cargo :: new (
191
214
builder,
192
- compiler ,
215
+ build_compiler ,
193
216
Mode :: Rustc ,
194
217
SourceType :: InTree ,
195
218
target,
196
219
Kind :: Check ,
197
220
) ;
198
221
199
- rustc_cargo ( builder, & mut cargo, target, & compiler , & self . crates ) ;
222
+ rustc_cargo ( builder, & mut cargo, target, & build_compiler , & self . crates ) ;
200
223
201
224
// Explicitly pass -p for all compiler crates -- this will force cargo
202
225
// to also check the tests/benches/examples for these crates, rather
@@ -211,17 +234,18 @@ impl Step for Rustc {
211
234
None ,
212
235
) ;
213
236
214
- let stamp = build_stamp:: librustc_stamp ( builder, compiler, target) . with_prefix ( "check" ) ;
237
+ let stamp =
238
+ build_stamp:: librustc_stamp ( builder, build_compiler, target) . with_prefix ( "check" ) ;
215
239
216
240
run_cargo ( builder, cargo, builder. config . free_args . clone ( ) , & stamp, vec ! [ ] , true , false ) ;
217
241
218
- let libdir = builder. sysroot_target_libdir ( compiler , target) ;
219
- let hostdir = builder. sysroot_target_libdir ( compiler , compiler . host ) ;
242
+ let libdir = builder. sysroot_target_libdir ( build_compiler , target) ;
243
+ let hostdir = builder. sysroot_target_libdir ( build_compiler , build_compiler . host ) ;
220
244
add_to_sysroot ( builder, & libdir, & hostdir, & stamp) ;
221
245
}
222
246
223
247
fn metadata ( & self ) -> Option < StepMetadata > {
224
- Some ( StepMetadata :: check ( "rustc" , self . target ) )
248
+ Some ( StepMetadata :: check ( "rustc" , self . target ) . built_by ( self . build_compiler ) )
225
249
}
226
250
}
227
251
@@ -462,7 +486,7 @@ fn run_tool_check_step(
462
486
let display_name = path. rsplit ( '/' ) . next ( ) . unwrap ( ) ;
463
487
let compiler = builder. compiler ( builder. top_stage , builder. config . host_target ) ;
464
488
465
- builder. ensure ( Rustc :: new ( target , builder ) ) ;
489
+ builder. ensure ( Rustc :: new ( builder , compiler , target ) ) ;
466
490
467
491
let mut cargo = prepare_tool_cargo (
468
492
builder,
0 commit comments