33
44mod version;
55
6+ use std:: collections:: HashMap ;
67use std:: env;
78use std:: ffi:: { OsStr , OsString } ;
89use std:: fmt:: Write as _;
@@ -114,10 +115,14 @@ fn show_error(msg: String) -> ! {
114115 std:: process:: exit ( 1 )
115116}
116117
117- // Determines whether a `--flag` is present.
118+ /// Determines whether a `--flag` is present.
118119fn has_arg_flag ( name : & str ) -> bool {
119- let mut args = std:: env:: args ( ) . take_while ( |val| val != "--" ) ;
120- args. any ( |val| val == name)
120+ num_arg_flag ( name) > 0
121+ }
122+
123+ /// Determines how many times a `--flag` is present.
124+ fn num_arg_flag ( name : & str ) -> usize {
125+ std:: env:: args ( ) . take_while ( |val| val != "--" ) . filter ( |val| val == name) . count ( )
121126}
122127
123128/// Yields all values of command line flag `name` as `Ok(arg)`, and all other arguments except
@@ -588,7 +593,7 @@ fn phase_cargo_miri(mut args: env::Args) {
588593 "`cargo miri` supports the following subcommands: `run`, `test`, and `setup`."
589594 ) ) ,
590595 } ;
591- let verbose = has_arg_flag ( "-v" ) ;
596+ let verbose = num_arg_flag ( "-v" ) ;
592597
593598 // We always setup.
594599 setup ( & subcommand) ;
@@ -685,15 +690,15 @@ fn phase_cargo_miri(mut args: env::Args) {
685690 cmd. env ( "MIRI_LOCAL_CRATES" , local_crates ( & metadata) ) ;
686691
687692 // Run cargo.
688- if verbose {
693+ if verbose > 0 {
689694 eprintln ! ( "[cargo-miri miri] RUSTC_WRAPPER={:?}" , cargo_miri_path) ;
690695 eprintln ! ( "[cargo-miri miri] {}={:?}" , target_runner_env_name, cargo_miri_path) ;
691696 if * target != host {
692697 eprintln ! ( "[cargo-miri miri] {}={:?}" , host_runner_env_name, cargo_miri_path) ;
693698 }
694699 eprintln ! ( "[cargo-miri miri] RUSTDOC={:?}" , cargo_miri_path) ;
695700 eprintln ! ( "[cargo-miri miri] {:?}" , cmd) ;
696- cmd. env ( "MIRI_VERBOSE" , "" ) ; // This makes the other phases verbose.
701+ cmd. env ( "MIRI_VERBOSE" , verbose . to_string ( ) ) ; // This makes the other phases verbose.
697702 }
698703 exec ( cmd)
699704}
@@ -752,7 +757,8 @@ fn phase_rustc(mut args: env::Args, phase: RustcPhase) {
752757 }
753758 }
754759
755- let verbose = std:: env:: var_os ( "MIRI_VERBOSE" ) . is_some ( ) ;
760+ let verbose = std:: env:: var ( "MIRI_VERBOSE" )
761+ . map_or ( 0 , |verbose| verbose. parse ( ) . expect ( "verbosity flag must be an integer" ) ) ;
756762 let target_crate = is_target_crate ( ) ;
757763 let print = get_arg_flag_value ( "--print" ) . is_some ( ) || has_arg_flag ( "-vV" ) ; // whether this is cargo/xargo invoking rustc to get some infos
758764
@@ -761,13 +767,13 @@ fn phase_rustc(mut args: env::Args, phase: RustcPhase) {
761767 // https://github.com/rust-lang/miri/issues/1724#issuecomment-787115693
762768 // As we store a JSON file instead of building the crate here, an empty file is fine.
763769 let dep_info_name = out_filename ( "" , ".d" ) ;
764- if verbose {
770+ if verbose > 0 {
765771 eprintln ! ( "[cargo-miri rustc] writing stub dep-info to `{}`" , dep_info_name. display( ) ) ;
766772 }
767773 File :: create ( dep_info_name) . expect ( "failed to create fake .d file" ) ;
768774
769775 let filename = out_filename ( "" , "" ) ;
770- if verbose {
776+ if verbose > 0 {
771777 eprintln ! ( "[cargo-miri rustc] writing run info to `{}`" , filename. display( ) ) ;
772778 }
773779 info. store ( & filename) ;
@@ -810,7 +816,7 @@ fn phase_rustc(mut args: env::Args, phase: RustcPhase) {
810816 cmd. args ( & env. args ) ;
811817 cmd. env ( "MIRI_BE_RUSTC" , "target" ) ;
812818
813- if verbose {
819+ if verbose > 0 {
814820 eprintln ! (
815821 "[cargo-miri rustc] captured input:\n {}" ,
816822 std:: str :: from_utf8( & env. stdin) . unwrap( )
@@ -877,6 +883,15 @@ fn phase_rustc(mut args: env::Args, phase: RustcPhase) {
877883 cmd. arg ( "-C" ) . arg ( "panic=abort" ) ;
878884 }
879885 } else {
886+ // For host crates (but not when we are printing), we might still have to set the sysroot.
887+ if !print {
888+ // When we're running `cargo-miri` from `x.py` we need to pass the sysroot explicitly as rustc
889+ // can't figure out the sysroot on its own unless it's from rustup.
890+ if let Some ( sysroot) = std:: env:: var_os ( "SYSROOT" ) {
891+ cmd. arg ( "--sysroot" ) . arg ( sysroot) ;
892+ }
893+ }
894+
880895 // For host crates or when we are printing, just forward everything.
881896 cmd. args ( args) ;
882897 }
@@ -888,8 +903,14 @@ fn phase_rustc(mut args: env::Args, phase: RustcPhase) {
888903 cmd. env ( "MIRI_BE_RUSTC" , if target_crate { "target" } else { "host" } ) ;
889904
890905 // Run it.
891- if verbose {
892- eprintln ! ( "[cargo-miri rustc] {:?}" , cmd) ;
906+ if verbose > 0 {
907+ eprint ! ( "[cargo-miri rustc] " ) ;
908+ if verbose > 1 {
909+ for ( key, value) in env_vars_from_cmd ( & cmd) {
910+ eprintln ! ( "{key}={value:?} \\ " ) ;
911+ }
912+ }
913+ eprintln ! ( "{:?}" , cmd) ;
893914 }
894915 exec ( cmd) ;
895916
@@ -908,6 +929,23 @@ fn phase_rustc(mut args: env::Args, phase: RustcPhase) {
908929 }
909930}
910931
932+ fn env_vars_from_cmd ( cmd : & Command ) -> Vec < ( String , String ) > {
933+ let mut envs = HashMap :: new ( ) ;
934+ for ( key, value) in std:: env:: vars ( ) {
935+ envs. insert ( key, value) ;
936+ }
937+ for ( key, value) in cmd. get_envs ( ) {
938+ if let Some ( value) = value {
939+ envs. insert ( key. to_str ( ) . unwrap ( ) . into ( ) , value. to_str ( ) . unwrap ( ) . to_owned ( ) ) ;
940+ } else {
941+ envs. remove ( key. to_str ( ) . unwrap ( ) ) ;
942+ }
943+ }
944+ let mut envs: Vec < _ > = envs. into_iter ( ) . collect ( ) ;
945+ envs. sort ( ) ;
946+ envs
947+ }
948+
911949#[ derive( Debug , Copy , Clone , PartialEq ) ]
912950enum RunnerPhase {
913951 /// `cargo` is running a binary
0 commit comments