3
3
4
4
mod version;
5
5
6
+ use std:: collections:: HashMap ;
6
7
use std:: env;
7
8
use std:: ffi:: { OsStr , OsString } ;
8
9
use std:: fmt:: Write as _;
@@ -114,10 +115,14 @@ fn show_error(msg: String) -> ! {
114
115
std:: process:: exit ( 1 )
115
116
}
116
117
117
- // Determines whether a `--flag` is present.
118
+ /// Determines whether a `--flag` is present.
118
119
fn 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 ( )
121
126
}
122
127
123
128
/// 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) {
588
593
"`cargo miri` supports the following subcommands: `run`, `test`, and `setup`."
589
594
) ) ,
590
595
} ;
591
- let verbose = has_arg_flag ( "-v" ) ;
596
+ let verbose = num_arg_flag ( "-v" ) ;
592
597
593
598
// We always setup.
594
599
setup ( & subcommand) ;
@@ -685,15 +690,15 @@ fn phase_cargo_miri(mut args: env::Args) {
685
690
cmd. env ( "MIRI_LOCAL_CRATES" , local_crates ( & metadata) ) ;
686
691
687
692
// Run cargo.
688
- if verbose {
693
+ if verbose > 0 {
689
694
eprintln ! ( "[cargo-miri miri] RUSTC_WRAPPER={:?}" , cargo_miri_path) ;
690
695
eprintln ! ( "[cargo-miri miri] {}={:?}" , target_runner_env_name, cargo_miri_path) ;
691
696
if * target != host {
692
697
eprintln ! ( "[cargo-miri miri] {}={:?}" , host_runner_env_name, cargo_miri_path) ;
693
698
}
694
699
eprintln ! ( "[cargo-miri miri] RUSTDOC={:?}" , cargo_miri_path) ;
695
700
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.
697
702
}
698
703
exec ( cmd)
699
704
}
@@ -752,7 +757,8 @@ fn phase_rustc(mut args: env::Args, phase: RustcPhase) {
752
757
}
753
758
}
754
759
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" ) ) ;
756
762
let target_crate = is_target_crate ( ) ;
757
763
let print = get_arg_flag_value ( "--print" ) . is_some ( ) || has_arg_flag ( "-vV" ) ; // whether this is cargo/xargo invoking rustc to get some infos
758
764
@@ -761,13 +767,13 @@ fn phase_rustc(mut args: env::Args, phase: RustcPhase) {
761
767
// https://github.com/rust-lang/miri/issues/1724#issuecomment-787115693
762
768
// As we store a JSON file instead of building the crate here, an empty file is fine.
763
769
let dep_info_name = out_filename ( "" , ".d" ) ;
764
- if verbose {
770
+ if verbose > 0 {
765
771
eprintln ! ( "[cargo-miri rustc] writing stub dep-info to `{}`" , dep_info_name. display( ) ) ;
766
772
}
767
773
File :: create ( dep_info_name) . expect ( "failed to create fake .d file" ) ;
768
774
769
775
let filename = out_filename ( "" , "" ) ;
770
- if verbose {
776
+ if verbose > 0 {
771
777
eprintln ! ( "[cargo-miri rustc] writing run info to `{}`" , filename. display( ) ) ;
772
778
}
773
779
info. store ( & filename) ;
@@ -810,7 +816,7 @@ fn phase_rustc(mut args: env::Args, phase: RustcPhase) {
810
816
cmd. args ( & env. args ) ;
811
817
cmd. env ( "MIRI_BE_RUSTC" , "target" ) ;
812
818
813
- if verbose {
819
+ if verbose > 0 {
814
820
eprintln ! (
815
821
"[cargo-miri rustc] captured input:\n {}" ,
816
822
std:: str :: from_utf8( & env. stdin) . unwrap( )
@@ -877,6 +883,15 @@ fn phase_rustc(mut args: env::Args, phase: RustcPhase) {
877
883
cmd. arg ( "-C" ) . arg ( "panic=abort" ) ;
878
884
}
879
885
} 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
+
880
895
// For host crates or when we are printing, just forward everything.
881
896
cmd. args ( args) ;
882
897
}
@@ -888,8 +903,14 @@ fn phase_rustc(mut args: env::Args, phase: RustcPhase) {
888
903
cmd. env ( "MIRI_BE_RUSTC" , if target_crate { "target" } else { "host" } ) ;
889
904
890
905
// 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) ;
893
914
}
894
915
exec ( cmd) ;
895
916
@@ -908,6 +929,23 @@ fn phase_rustc(mut args: env::Args, phase: RustcPhase) {
908
929
}
909
930
}
910
931
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
+
911
949
#[ derive( Debug , Copy , Clone , PartialEq ) ]
912
950
enum RunnerPhase {
913
951
/// `cargo` is running a binary
0 commit comments