@@ -80,7 +80,36 @@ fn get_arg_flag_value(name: &str) -> Option<String> {
8080    } 
8181} 
8282
83- fn  list_targets ( )  -> ( impl  Iterator < Item =cargo_metadata:: Target > ,  String )  { 
83+ fn  is_build_dep ( mut  args :  impl  Iterator < Item  = String > )  -> bool  { 
84+     args. any ( |arg| arg. starts_with ( "--emit=" )  && arg. contains ( "link" ) ) 
85+ } 
86+ 
87+ // Returns whether or not Cargo invoked the wrapper (this binary) to compile 
88+ // the final, target crate (either a test for 'cargo test', or a binary for 'cargo run') 
89+ // Right now, this is an awful hack that checks several different pieces of information 
90+ // to try to figure out if the crate being compiled is the right one. 
91+ // Ideally, Cargo would set en environment variable indicating whether or 
92+ // not the wrapper is being invoked on the target crate. 
93+ // For now, this is the best we can do 
94+ fn  is_target_crate ( is_build_script :  bool )  -> bool  { 
95+     // Cargo sets this to the directory containing the manifest of the crate 
96+     // the wrapper is being invoekd to compile. This should be unique 
97+     // across the entire build (except for build scripts, which we handle below). 
98+     // We cannot check the crate name, since this may not be unique 
99+     // (e.g. if the build contains multiple versions of the same crate, 
100+     // or the same crate from multiple sources) 
101+     let  manifest_dir = std:: env:: var ( "CARGO_MANIFEST_DIR" ) . ok ( ) ; 
102+ 
103+     // The manifest directory for our target crate. This is set by `cargo-miri` 
104+     // (the original invoation by the user) by using `cargo_metadata` to locate 
105+     // the manifest. 
106+     let  expected_dir = std:: env:: var ( "MIRI_MAGIC_DIR" ) . expect ( "MIRI_MAGIC_DIR not set!" ) ; 
107+ 
108+     manifest_dir == Some ( expected_dir)  && !is_build_script
109+ 
110+ } 
111+ 
112+ fn  read_cargo_metadata ( )  -> ( impl  Iterator < Item =cargo_metadata:: Target > ,  String )  { 
84113    // We need to get the manifest, and then the metadata, to enumerate targets. 
85114    let  manifest_path = get_arg_flag_value ( "--manifest-path" ) . map ( |m|
86115        Path :: new ( & m) . canonicalize ( ) . unwrap ( ) 
@@ -411,7 +440,7 @@ fn in_cargo_miri() {
411440        return ; 
412441    } 
413442
414-     let  ( targets,  root_dir)  = list_targets ( ) ; 
443+     let  ( targets,  root_dir)  = read_cargo_metadata ( ) ; 
415444
416445    // Now run the command. 
417446    for  target in  targets { 
@@ -460,14 +489,7 @@ fn in_cargo_miri() {
460489
461490        cmd. env ( "MIRI_MAGIC_ARGS" ,  prefixed_args) ; 
462491        cmd. env ( "MIRI_MAGIC_DIR" ,  root_dir. clone ( ) ) ; 
463-         // Add `--` (to end the `cargo` flags), and then the user flags. We add markers around the 
464-         // user flags to be able to identify them later.  "cargo rustc" adds more stuff after this, 
465-         // so we have to mark both the beginning and the end. 
466-         /*cmd 
467-             .arg("--") 
468-             .arg("cargo-miri-marker-begin") 
469-             .args(args) 
470-             .arg("cargo-miri-marker-end");*/ 
492+ 
471493        let  path = std:: env:: current_exe ( ) . expect ( "current executable path invalid" ) ; 
472494        cmd. env ( "RUSTC_WRAPPER" ,  path) ; 
473495        if  verbose { 
@@ -492,57 +514,34 @@ fn inside_cargo_rustc() {
492514
493515    let  rustc_args = std:: env:: args ( ) . skip ( 2 ) ;  // skip `cargo rustc` 
494516
495-     let  ( mut  args,  is_build_script)  = if  std:: env:: args ( ) . skip ( 2 ) . find ( |arg| arg == "build_script_build" ) . is_some ( )  { 
496-         ( rustc_args. collect ( ) ,  true ) 
517+ 
518+     eprintln ! ( "cargo rustc env: {:?}" ,  std:: env:: vars( ) . collect:: <Vec <_>>( ) ) ; 
519+ 
520+     let  in_build_script = is_build_dep ( std:: env:: args ( ) . skip ( 2 ) ) ; 
521+ 
522+ 
523+     let  mut  args = if  in_build_script { 
524+         rustc_args. collect ( ) 
497525    }  else  { 
498526        let  mut  args:  Vec < String >  = rustc_args
499527            . chain ( Some ( "--sysroot" . to_owned ( ) ) ) 
500528            . chain ( Some ( sysroot) ) 
501529            . collect ( ) ; 
502530        args. splice ( 0 ..0 ,  miri:: miri_default_args ( ) . iter ( ) . map ( ToString :: to_string) ) ; 
503-         ( args,   false ) 
531+         args
504532    } ; 
505533
506- 
507-     let  is_test = args. contains ( & "--test" . to_string ( ) ) ; 
508-     let  mut  is_bin = false ; 
509-     for  ( i,  arg)  in  args. iter ( ) . enumerate ( )  { 
510-         if  arg == "--crate-type"  && args[ i + 1 ]  == "bin"  { 
511-             is_bin = true ; 
512-             break ; 
513-         } 
514-     } 
515- 
516- 
517-     let  manifest_dir = std:: env:: var ( "CARGO_MANIFEST_DIR" ) . ok ( ) ; 
518-     let  expected_dir = std:: env:: var ( "MIRI_MAGIC_DIR" ) . ok ( ) ; 
519- 
520-     //eprintln!("Manifest: {:?}", manifest_dir); 
521-     //eprintln!("Magic dir: {:?}", expected_dir); 
522- 
523- 
524534    // See if we can find the `cargo-miri` markers. Those only get added to the binary we want to 
525535    // run. They also serve to mark the user-defined arguments, which we have to move all the way 
526536    // to the end (they get added somewhere in the middle). 
527-     //let needs_miri = if let Some(begin) = args.iter().position(|arg| arg == "cargo-miri-marker-begin") { 
528-     let  needs_miri = if  manifest_dir == expected_dir && ( is_bin || is_test)  && !is_build_script { 
529-         /*let end = args 
530-             .iter() 
531-             .position(|arg| arg == "cargo-miri-marker-end") 
532-             .expect("cannot find end marker"); 
533-         // These mark the user arguments. We remove the first and last as they are the markers. 
534-         let mut user_args = args.drain(begin..=end);*/ 
535- 
536-         let  raw_args = std:: env:: var ( "MIRI_MAGIC_ARGS" ) . expect ( "Misisng magic!" ) ; 
537+     let  needs_miri = if  is_target_crate ( in_build_script)  { 
538+         let  raw_args = std:: env:: var ( "MIRI_MAGIC_ARGS" ) . expect ( "Missing magic!" ) ; 
537539        let  mut  user_args = vec ! [ ] ; 
538540        let  mut  slice = raw_args. as_str ( ) ; 
539-         //eprintln!("Raw args: {:?}", raw_args); 
540541        loop  { 
541542            match  slice. find ( ';' )  { 
542543                Some ( pos)  => { 
543-                     //eprintln!("Slice: {:?} Len str: (pos {}) {:?}", slice, pos, &slice[..(pos)]); 
544544                    let  len:  usize  = slice[ ..( pos) ] . parse ( ) . unwrap ( ) ; 
545-                     //eprintln!("Parsed len: {:?}", len); 
546545                    let  arg = slice[ ( pos+1 ) ..=( pos+len) ] . to_string ( ) ; 
547546                    user_args. push ( arg) ; 
548547                    slice = & slice[ ( pos+len+1 ) ..] ; 
@@ -551,12 +550,6 @@ fn inside_cargo_rustc() {
551550            } 
552551        } 
553552
554-         //println!("User args: {:?}", user_args); 
555- 
556-         //assert_eq!(user_args.next().unwrap(), "cargo-miri-marker-begin"); 
557-         //assert_eq!(user_args.next_back().unwrap(), "cargo-miri-marker-end"); 
558-         // Collect the rest and add it back at the end. 
559-         //let mut user_args = user_args.collect::<Vec<String>>(); 
560553        args. append ( & mut  user_args) ; 
561554        // Run this in Miri. 
562555        true 
0 commit comments