@@ -236,18 +236,34 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
236236 is_bin || is_test
237237 }
238238
239- fn out_filename ( prefix : & str , suffix : & str ) -> PathBuf {
239+ fn out_filename ( ) -> PathBuf {
240240 if let Some ( out_dir) = get_arg_flag_value ( "--out-dir" ) {
241241 let mut path = PathBuf :: from ( out_dir) ;
242- path. push ( format ! (
243- "{}{}{}{}" ,
244- prefix,
245- get_arg_flag_value( "--crate-name" ) . unwrap( ) ,
246- // This is technically a `-C` flag but the prefix seems unique enough...
247- // (and cargo passes this before the filename so it should be unique)
248- get_arg_flag_value( "extra-filename" ) . unwrap_or_default( ) ,
249- suffix,
250- ) ) ;
242+ // Ask rustc for the filename (since that is target-dependent).
243+ let mut rustc = miri_for_host ( ) ; // sysroot doesn't matter for this so we just use the host
244+ rustc. arg ( "--print" ) . arg ( "file-names" ) ;
245+ for flag in [ "--crate-name" , "--crate-type" , "--target" ] {
246+ if let Some ( val) = get_arg_flag_value ( flag) {
247+ rustc. arg ( flag) . arg ( val) ;
248+ }
249+ }
250+ // This is technically passed as `-C extra-filename=...`, but the prefix seems unique
251+ // enough... (and cargo passes this before the filename so it should be unique)
252+ if let Some ( extra) = get_arg_flag_value ( "extra-filename" ) {
253+ rustc. arg ( "-C" ) . arg ( format ! ( "extra-filename={extra}" ) ) ;
254+ }
255+ rustc. arg ( "-" ) ;
256+
257+ let output = rustc. output ( ) . expect ( "cannot run rustc to determine file name" ) ;
258+ assert ! (
259+ output. status. success( ) ,
260+ "rustc failed when determining file name:\n {output:?}"
261+ ) ;
262+ let output =
263+ String :: from_utf8 ( output. stdout ) . expect ( "rustc returned non-UTF-8 filename" ) ;
264+ let output = output. lines ( ) . next ( ) . unwrap ( ) ;
265+
266+ path. push ( output) ;
251267 path
252268 } else {
253269 let out_file = get_arg_flag_value ( "-o" ) . unwrap ( ) ;
@@ -267,24 +283,27 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
267283 let info_query = get_arg_flag_value ( "--print" ) . is_some ( ) || has_arg_flag ( "-vV" ) ;
268284
269285 let store_json = |info : CrateRunInfo | {
270- // Create a stub .d file to stop Cargo from "rebuilding" the crate:
271- // https://github.com/rust-lang/miri/issues/1724#issuecomment-787115693
272- // As we store a JSON file instead of building the crate here, an empty file is fine.
273- let dep_info_name = out_filename ( "" , ".d" ) ;
274- if verbose > 0 {
275- eprintln ! ( "[cargo-miri rustc] writing stub dep-info to `{}`" , dep_info_name. display( ) ) ;
286+ if get_arg_flag_value ( "--emit" ) . unwrap_or_default ( ) . split ( ',' ) . any ( |e| e == "dep-info" ) {
287+ // Create a stub .d file to stop Cargo from "rebuilding" the crate:
288+ // https://github.com/rust-lang/miri/issues/1724#issuecomment-787115693
289+ // As we store a JSON file instead of building the crate here, an empty file is fine.
290+ let dep_info_name = format ! (
291+ "{}/{}{}.d" ,
292+ get_arg_flag_value( "--out-dir" ) . unwrap( ) ,
293+ get_arg_flag_value( "--crate-name" ) . unwrap( ) ,
294+ get_arg_flag_value( "extra-filename" ) . unwrap_or_default( ) ,
295+ ) ;
296+ if verbose > 0 {
297+ eprintln ! ( "[cargo-miri rustc] writing stub dep-info to `{dep_info_name}`" ) ;
298+ }
299+ File :: create ( dep_info_name) . expect ( "failed to create fake .d file" ) ;
276300 }
277- File :: create ( dep_info_name) . expect ( "failed to create fake .d file" ) ;
278301
279- let filename = out_filename ( "" , "" ) ;
302+ let filename = out_filename ( ) ;
280303 if verbose > 0 {
281304 eprintln ! ( "[cargo-miri rustc] writing run info to `{}`" , filename. display( ) ) ;
282305 }
283306 info. store ( & filename) ;
284- // For Windows and WASM, do the same thing again with `.exe`/`.wasm` appended to the filename.
285- // (Need to do this here as cargo moves that "binary" to a different place before running it.)
286- info. store ( & out_filename ( "" , ".exe" ) ) ;
287- info. store ( & out_filename ( "" , ".wasm" ) ) ;
288307 } ;
289308
290309 let runnable_crate = !info_query && is_runnable_crate ( ) ;
@@ -340,7 +359,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
340359 eprintln ! ( "[cargo-miri rustc inside rustdoc] going to run:\n {cmd:?}" ) ;
341360 }
342361
343- exec_with_pipe ( cmd, & env. stdin , format ! ( "{}.stdin" , out_filename( "" , "" ) . display( ) ) ) ;
362+ exec_with_pipe ( cmd, & env. stdin , format ! ( "{}.stdin" , out_filename( ) . display( ) ) ) ;
344363 }
345364
346365 return ;
@@ -422,15 +441,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
422441 // Create a stub .rlib file if "link" was requested by cargo.
423442 // This is necessary to prevent cargo from doing rebuilds all the time.
424443 if emit_link_hack {
425- // Some platforms prepend "lib", some do not... let's just create both files.
426- File :: create ( out_filename ( "lib" , ".rlib" ) ) . expect ( "failed to create fake .rlib file" ) ;
427- File :: create ( out_filename ( "" , ".rlib" ) ) . expect ( "failed to create fake .rlib file" ) ;
428- // Just in case this is a cdylib or staticlib, also create those fake files.
429- File :: create ( out_filename ( "lib" , ".so" ) ) . expect ( "failed to create fake .so file" ) ;
430- File :: create ( out_filename ( "lib" , ".a" ) ) . expect ( "failed to create fake .a file" ) ;
431- File :: create ( out_filename ( "lib" , ".dylib" ) ) . expect ( "failed to create fake .dylib file" ) ;
432- File :: create ( out_filename ( "" , ".dll" ) ) . expect ( "failed to create fake .dll file" ) ;
433- File :: create ( out_filename ( "" , ".lib" ) ) . expect ( "failed to create fake .lib file" ) ;
444+ File :: create ( out_filename ( ) ) . expect ( "failed to create fake .rlib file" ) ;
434445 }
435446
436447 debug_cmd ( "[cargo-miri rustc]" , verbose, & cmd) ;
0 commit comments