@@ -86,11 +86,15 @@ fn get_arg_flag_value(name: &str) -> Option<String> {
8686 }
8787}
8888
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 {
9191 let mut path = std:: env:: current_exe ( ) . expect ( "current executable path invalid" ) ;
9292 path. set_file_name ( "miri" ) ;
93- Command :: new ( path)
93+ path
94+ }
95+
96+ fn miri ( ) -> Command {
97+ Command :: new ( find_miri ( ) )
9498}
9599
96100fn cargo ( ) -> Command {
@@ -322,7 +326,8 @@ fn setup(subcommand: MiriCommand) {
322326 show_error ( format ! ( "Given Rust source directory `{}` does not exist." , rust_src. display( ) ) ) ;
323327 }
324328
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.
326331 let dirs = directories:: ProjectDirs :: from ( "org" , "rust-lang" , "miri" ) . unwrap ( ) ;
327332 let dir = dirs. cache_dir ( ) ;
328333 if !dir. exists ( ) {
@@ -360,20 +365,31 @@ path = "lib.rs"
360365 )
361366 . unwrap ( ) ;
362367 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 ;
364372 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.
367375 let mut command = xargo_check ( ) ;
368376 command. arg ( "build" ) . arg ( "-q" ) ;
377+ command. arg ( "--target" ) . arg ( target) ;
369378 command. current_dir ( & dir) ;
370- command. env ( "RUSTFLAGS" , miri:: miri_default_args ( ) . join ( " " ) ) ;
371379 command. env ( "XARGO_HOME" , & dir) ;
372380 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 ( ) ) ;
376390 }
391+ command. env ( "MIRI_BE_RUSTC" , "1" ) ;
392+ command. env ( "RUSTFLAGS" , miri:: miri_default_args ( ) . join ( " " ) ) ;
377393 // Finally run it!
378394 if command. status ( ) . expect ( "failed to run xargo" ) . success ( ) . not ( ) {
379395 show_error ( format ! ( "Failed to run xargo" ) ) ;
@@ -382,12 +398,11 @@ path = "lib.rs"
382398 // That should be it! But we need to figure out where xargo built stuff.
383399 // Unfortunately, it puts things into a different directory when the
384400 // 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) } ;
390402 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
391406 if print_sysroot {
392407 // Print just the sysroot and nothing else; this way we do not need any escaping.
393408 println ! ( "{}" , sysroot. display( ) ) ;
@@ -476,7 +491,7 @@ fn in_cargo_miri() {
476491
477492 // Set `RUSTC_WRAPPER` to ourselves. Cargo will prepend that binary to its usual invocation,
478493 // 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`.)
480495 let path = std:: env:: current_exe ( ) . expect ( "current executable path invalid" ) ;
481496 cmd. env ( "RUSTC_WRAPPER" , path) ;
482497 if verbose {
0 commit comments