4
4
//! However, this contains ~all test parts we expect people to be able to build and run locally.
5
5
6
6
use std:: collections:: HashSet ;
7
+ use std:: env:: join_paths;
7
8
use std:: ffi:: { OsStr , OsString } ;
8
9
use std:: path:: { Path , PathBuf } ;
9
10
use std:: { env, fs, iter} ;
10
11
12
+ use build_helper:: exit;
11
13
#[ cfg( feature = "tracing" ) ]
12
14
use tracing:: instrument;
13
15
@@ -242,8 +244,12 @@ impl Step for Cargotest {
242
244
}
243
245
244
246
fn make_run ( run : RunConfig < ' _ > ) {
245
- // FIXME: support testing stage 0 cargo?
246
- assert ! ( run. builder. top_stage > 0 ) ;
247
+ if run. builder . top_stage == 0 {
248
+ eprintln ! (
249
+ "ERROR: running cargotest with stage 0 is currently unsupported. Use at least stage 1."
250
+ ) ;
251
+ exit ! ( 1 ) ;
252
+ }
247
253
run. builder . ensure ( Cargotest {
248
254
build_compiler : run. builder . compiler ( run. builder . top_stage - 1 , run. target ) ,
249
255
host : run. target ,
@@ -322,14 +328,18 @@ impl Step for Cargo {
322
328
323
329
/// Runs `cargo test` for `cargo` packaged with Rust.
324
330
fn run ( self , builder : & Builder < ' _ > ) {
325
- // FIXME: we now use the same compiler to build cargo and then we also test that compiler
326
- // using cargo.
327
- // We could build cargo using a different compiler, but that complicates some things,
328
- // because when we run cargo tests, the crates that are being compiled are accessing the
329
- // sysroot of the build compiler, rather than the compiler being tested.
330
- // Since these two compilers are currently the same, it works.
331
+ // When we do a "stage 1 cargo test", it means that we test the stage 1 rustc
332
+ // using stage 1 cargo. So we actually build cargo using the stage 0 compiler, and then
333
+ // run its tests against the stage 1 compiler (called `tested_compiler` below).
331
334
builder. ensure ( tool:: Cargo :: from_build_compiler ( self . build_compiler , self . host ) ) ;
332
335
336
+ let tested_compiler = builder. compiler ( self . build_compiler . stage + 1 , self . host ) ;
337
+ builder. std ( tested_compiler, self . host ) ;
338
+ // We also need to build rustdoc for cargo tests
339
+ // It will be located in the bindir of `tested_compiler`, so we don't need to explicitly
340
+ // pass its path to Cargo.
341
+ builder. rustdoc_for_compiler ( tested_compiler) ;
342
+
333
343
let cargo = tool:: prepare_tool_cargo (
334
344
builder,
335
345
self . build_compiler ,
@@ -350,7 +360,27 @@ impl Step for Cargo {
350
360
// Forcibly disable tests using nightly features since any changes to
351
361
// those features won't be able to land.
352
362
cargo. env ( "CARGO_TEST_DISABLE_NIGHTLY" , "1" ) ;
353
- cargo. env ( "PATH" , path_for_cargo ( builder, self . build_compiler ) ) ;
363
+
364
+ // Configure PATH to find the right rustc. NB. we have to use PATH
365
+ // and not RUSTC because the Cargo test suite has tests that will
366
+ // fail if rustc is not spelled `rustc`.
367
+ cargo. env ( "PATH" , bin_path_for_cargo ( builder, tested_compiler) ) ;
368
+
369
+ // The `cargo` command configured above has dylib dir path set to the `build_compiler`'s
370
+ // libdir. That causes issues in cargo test, because the programs that cargo compiles are
371
+ // incorrectly picking that libdir, even though they should be picking the
372
+ // `tested_compiler`'s libdir. We thus have to override the precedence here.
373
+ let existing_dylib_path = cargo
374
+ . get_envs ( )
375
+ . find ( |( k, _) | * k == OsStr :: new ( dylib_path_var ( ) ) )
376
+ . and_then ( |( _, v) | v)
377
+ . unwrap_or ( OsStr :: new ( "" ) ) ;
378
+ cargo. env (
379
+ dylib_path_var ( ) ,
380
+ join_paths ( [ builder. rustc_libdir ( tested_compiler) . as_ref ( ) , existing_dylib_path] )
381
+ . unwrap_or_default ( ) ,
382
+ ) ;
383
+
354
384
// Cargo's test suite uses `CARGO_RUSTC_CURRENT_DIR` to determine the path that `file!` is
355
385
// relative to. Cargo no longer sets this env var, so we have to do that. This has to be the
356
386
// same value as `-Zroot-dir`.
@@ -859,10 +889,7 @@ impl Step for Clippy {
859
889
}
860
890
}
861
891
862
- fn path_for_cargo ( builder : & Builder < ' _ > , compiler : Compiler ) -> OsString {
863
- // Configure PATH to find the right rustc. NB. we have to use PATH
864
- // and not RUSTC because the Cargo test suite has tests that will
865
- // fail if rustc is not spelled `rustc`.
892
+ fn bin_path_for_cargo ( builder : & Builder < ' _ > , compiler : Compiler ) -> OsString {
866
893
let path = builder. sysroot ( compiler) . join ( "bin" ) ;
867
894
let old_path = env:: var_os ( "PATH" ) . unwrap_or_default ( ) ;
868
895
env:: join_paths ( iter:: once ( path) . chain ( env:: split_paths ( & old_path) ) ) . expect ( "" )
0 commit comments