@@ -86,11 +86,15 @@ fn get_arg_flag_value(name: &str) -> Option<String> {
86
86
}
87
87
}
88
88
89
- /// Returns a command for the right `miri` binary.
90
- fn miri ( ) -> Command {
89
+ /// Returns the path to the `miri` binary
90
+ fn find_miri ( ) -> PathBuf {
91
91
let mut path = std:: env:: current_exe ( ) . expect ( "current executable path invalid" ) ;
92
92
path. set_file_name ( "miri" ) ;
93
- Command :: new ( path)
93
+ path
94
+ }
95
+
96
+ fn miri ( ) -> Command {
97
+ Command :: new ( find_miri ( ) )
94
98
}
95
99
96
100
fn cargo ( ) -> Command {
@@ -322,7 +326,8 @@ fn setup(subcommand: MiriCommand) {
322
326
show_error ( format ! ( "Given Rust source directory `{}` does not exist." , rust_src. display( ) ) ) ;
323
327
}
324
328
325
- // Next, we need our own libstd. We will do this work in whatever is a good cache dir for this platform.
329
+ // Next, we need our own libstd. Prepare a xargo project for that purpose.
330
+ // We will do this work in whatever is a good cache dir for this platform.
326
331
let dirs = directories:: ProjectDirs :: from ( "org" , "rust-lang" , "miri" ) . unwrap ( ) ;
327
332
let dir = dirs. cache_dir ( ) ;
328
333
if !dir. exists ( ) {
@@ -360,20 +365,31 @@ path = "lib.rs"
360
365
)
361
366
. unwrap ( ) ;
362
367
File :: create ( dir. join ( "lib.rs" ) ) . unwrap ( ) ;
363
- // Prepare xargo invocation.
368
+
369
+ // Determine architectures.
370
+ // We always need to set a target so rustc bootstrap can tell apart host from target crates.
371
+ let host = rustc_version:: version_meta ( ) . unwrap ( ) . host ;
364
372
let target = get_arg_flag_value ( "--target" ) ;
365
- let print_sysroot = subcommand == MiriCommand :: Setup
366
- && has_arg_flag ( "--print-sysroot" ) ; // whether we just print the sysroot path
373
+ let target = target . as_ref ( ) . unwrap_or ( & host ) ;
374
+ // Now invoke xargo.
367
375
let mut command = xargo_check ( ) ;
368
376
command. arg ( "build" ) . arg ( "-q" ) ;
377
+ command. arg ( "--target" ) . arg ( target) ;
369
378
command. current_dir ( & dir) ;
370
- command. env ( "RUSTFLAGS" , miri:: miri_default_args ( ) . join ( " " ) ) ;
371
379
command. env ( "XARGO_HOME" , & dir) ;
372
380
command. env ( "XARGO_RUST_SRC" , & rust_src) ;
373
- // Handle target flag.
374
- if let Some ( target) = & target {
375
- command. arg ( "--target" ) . arg ( target) ;
381
+ // Use Miri as rustc to build a libstd compatible with us (and use the right flags).
382
+ // However, when we are running in bootstrap, we cannot just overwrite `RUSTC`,
383
+ // because we still need bootstrap to distinguish between host and target crates.
384
+ // In that case we overwrite `RUSTC_REAL` instead which determines the rustc used
385
+ // for target crates.
386
+ if env:: var_os ( "RUSTC_STAGE" ) . is_some ( ) {
387
+ command. env ( "RUSTC_REAL" , find_miri ( ) ) ;
388
+ } else {
389
+ command. env ( "RUSTC" , find_miri ( ) ) ;
376
390
}
391
+ command. env ( "MIRI_BE_RUSTC" , "1" ) ;
392
+ command. env ( "RUSTFLAGS" , miri:: miri_default_args ( ) . join ( " " ) ) ;
377
393
// Finally run it!
378
394
if command. status ( ) . expect ( "failed to run xargo" ) . success ( ) . not ( ) {
379
395
show_error ( format ! ( "Failed to run xargo" ) ) ;
@@ -382,12 +398,11 @@ path = "lib.rs"
382
398
// That should be it! But we need to figure out where xargo built stuff.
383
399
// Unfortunately, it puts things into a different directory when the
384
400
// architecture matches the host.
385
- let is_host = match & target {
386
- None => true ,
387
- Some ( target) => target == & rustc_version:: version_meta ( ) . unwrap ( ) . host ,
388
- } ;
389
- let sysroot = if is_host { dir. join ( "HOST" ) } else { PathBuf :: from ( dir) } ;
401
+ let sysroot = if target == & host { dir. join ( "HOST" ) } else { PathBuf :: from ( dir) } ;
390
402
std:: env:: set_var ( "MIRI_SYSROOT" , & sysroot) ; // pass the env var to the processes we spawn, which will turn it into "--sysroot" flags
403
+ // Figure out what to print.
404
+ let print_sysroot = subcommand == MiriCommand :: Setup
405
+ && has_arg_flag ( "--print-sysroot" ) ; // whether we just print the sysroot path
391
406
if print_sysroot {
392
407
// Print just the sysroot and nothing else; this way we do not need any escaping.
393
408
println ! ( "{}" , sysroot. display( ) ) ;
@@ -476,7 +491,7 @@ fn in_cargo_miri() {
476
491
477
492
// Set `RUSTC_WRAPPER` to ourselves. Cargo will prepend that binary to its usual invocation,
478
493
// i.e., the first argument is `rustc` -- which is what we use in `main` to distinguish
479
- // the two codepaths.
494
+ // the two codepaths. (That extra argument is why we prefer this over setting `RUSTC`.)
480
495
let path = std:: env:: current_exe ( ) . expect ( "current executable path invalid" ) ;
481
496
cmd. env ( "RUSTC_WRAPPER" , path) ;
482
497
if verbose {
0 commit comments