@@ -143,6 +143,18 @@ fn get_arg_flag_value(name: &str) -> Option<String> {
143143 ArgFlagValueIter :: new ( name) . next ( )
144144}
145145
146+ fn forward_patched_extern_arg ( args : & mut impl Iterator < Item = String > , cmd : & mut Command ) {
147+ cmd. arg ( "--extern" ) ; // always forward flag, but adjust filename:
148+ let path = args. next ( ) . expect ( "`--extern` should be followed by a filename" ) ;
149+ if let Some ( lib) = path. strip_suffix ( ".rlib" ) {
150+ // If this is an rlib, make it an rmeta.
151+ cmd. arg ( format ! ( "{}.rmeta" , lib) ) ;
152+ } else {
153+ // Some other extern file (e.g. a `.so`). Forward unchanged.
154+ cmd. arg ( path) ;
155+ }
156+ }
157+
146158/// Returns the path to the `miri` binary
147159fn find_miri ( ) -> PathBuf {
148160 if let Some ( path) = env:: var_os ( "MIRI" ) {
@@ -553,7 +565,7 @@ fn phase_cargo_miri(mut args: env::Args) {
553565 exec ( cmd)
554566}
555567
556- fn phase_cargo_rustc ( args : env:: Args ) {
568+ fn phase_cargo_rustc ( mut args : env:: Args ) {
557569 /// Determines if we are being invoked (as rustc) to build a crate for
558570 /// the "target" architecture, in contrast to the "host" architecture.
559571 /// Host crates are for build scripts and proc macros and still need to
@@ -596,15 +608,6 @@ fn phase_cargo_rustc(args: env::Args) {
596608 let target_crate = is_target_crate ( ) ;
597609 let print = get_arg_flag_value ( "--print" ) . is_some ( ) ; // whether this is cargo passing `--print` to get some infos
598610
599- // cdylib is just skipped, we cannot interpret it and do not need it
600- // for the rest of the build either.
601- if get_arg_flag_value ( "--crate-type" ) . as_deref ( ) == Some ( "cdylib" ) {
602- if verbose {
603- eprint ! ( "[cargo-miri rustc] (cdylib skipped)" ) ;
604- }
605- return ;
606- }
607-
608611 let store_json = |info : CrateRunInfo | {
609612 let filename = out_filename ( "" , "" ) ;
610613 if verbose {
@@ -643,7 +646,7 @@ fn phase_cargo_rustc(args: env::Args) {
643646 if !print && target_crate {
644647 // Forward arguments, but remove "link" from "--emit" to make this a check-only build.
645648 let emit_flag = "--emit" ;
646- for arg in args {
649+ while let Some ( arg) = args. next ( ) {
647650 if arg. starts_with ( emit_flag) {
648651 // Patch this argument. First, extract its value.
649652 let val = & arg[ emit_flag. len ( ) ..] ;
@@ -659,6 +662,10 @@ fn phase_cargo_rustc(args: env::Args) {
659662 }
660663 }
661664 cmd. arg ( format ! ( "{}={}" , emit_flag, val. join( "," ) ) ) ;
665+ } else if arg == "--extern" {
666+ // Patch `--extern` filenames, since Cargo sometimes passes stub `.rlib` files:
667+ // https://github.com/rust-lang/miri/issues/1705
668+ forward_patched_extern_arg ( & mut args, & mut cmd) ;
662669 } else {
663670 cmd. arg ( arg) ;
664671 }
@@ -734,21 +741,11 @@ fn phase_cargo_runner(binary: &Path, binary_args: env::Args) {
734741 // but when we run here, cargo does not interpret the JSON any more. `--json`
735742 // then also nees to be dropped.
736743 let mut args = info. args . into_iter ( ) ;
737- let extern_flag = "--extern" ;
738744 let error_format_flag = "--error-format" ;
739745 let json_flag = "--json" ;
740746 while let Some ( arg) = args. next ( ) {
741- if arg == extern_flag {
742- cmd. arg ( extern_flag) ; // always forward flag, but adjust filename
743- // `--extern` is always passed as a separate argument by cargo.
744- let next_arg = args. next ( ) . expect ( "`--extern` should be followed by a filename" ) ;
745- if let Some ( next_lib) = next_arg. strip_suffix ( ".rlib" ) {
746- // If this is an rlib, make it an rmeta.
747- cmd. arg ( format ! ( "{}.rmeta" , next_lib) ) ;
748- } else {
749- // Some other extern file (e.g., a `.so`). Forward unchanged.
750- cmd. arg ( next_arg) ;
751- }
747+ if arg == "--extern" {
748+ forward_patched_extern_arg ( & mut args, & mut cmd) ;
752749 } else if arg. starts_with ( error_format_flag) {
753750 let suffix = & arg[ error_format_flag. len ( ) ..] ;
754751 assert ! ( suffix. starts_with( '=' ) ) ;
0 commit comments