@@ -236,22 +236,36 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
236
236
is_bin || is_test
237
237
}
238
238
239
- fn out_filename ( prefix : & str , suffix : & str ) -> PathBuf {
240
- if let Some ( out_dir) = get_arg_flag_value ( "--out-dir" ) {
241
- 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
- ) ) ;
251
- path
239
+ fn out_filenames ( ) -> Vec < PathBuf > {
240
+ if let Some ( out_file) = get_arg_flag_value ( "-o" ) {
241
+ // `-o` has precedence over `--out-dir`.
242
+ vec ! [ PathBuf :: from( out_file) ]
252
243
} else {
253
- let out_file = get_arg_flag_value ( "-o" ) . unwrap ( ) ;
254
- PathBuf :: from ( out_file)
244
+ let out_dir = get_arg_flag_value ( "--out-dir" ) . unwrap_or_default ( ) ;
245
+ let path = PathBuf :: from ( out_dir) ;
246
+ // Ask rustc for the filename (since that is target-dependent).
247
+ let mut rustc = miri_for_host ( ) ; // sysroot doesn't matter for this so we just use the host
248
+ rustc. arg ( "--print" ) . arg ( "file-names" ) ;
249
+ for flag in [ "--crate-name" , "--crate-type" , "--target" ] {
250
+ for val in get_arg_flag_values ( flag) {
251
+ rustc. arg ( flag) . arg ( val) ;
252
+ }
253
+ }
254
+ // This is technically passed as `-C extra-filename=...`, but the prefix seems unique
255
+ // enough... (and cargo passes this before the filename so it should be unique)
256
+ if let Some ( extra) = get_arg_flag_value ( "extra-filename" ) {
257
+ rustc. arg ( "-C" ) . arg ( format ! ( "extra-filename={extra}" ) ) ;
258
+ }
259
+ rustc. arg ( "-" ) ;
260
+
261
+ let output = rustc. output ( ) . expect ( "cannot run rustc to determine file name" ) ;
262
+ assert ! (
263
+ output. status. success( ) ,
264
+ "rustc failed when determining file name:\n {output:?}"
265
+ ) ;
266
+ let output =
267
+ String :: from_utf8 ( output. stdout ) . expect ( "rustc returned non-UTF-8 filename" ) ;
268
+ output. lines ( ) . filter ( |l| !l. is_empty ( ) ) . map ( |l| path. join ( l) ) . collect ( )
255
269
}
256
270
}
257
271
@@ -267,24 +281,28 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
267
281
let info_query = get_arg_flag_value ( "--print" ) . is_some ( ) || has_arg_flag ( "-vV" ) ;
268
282
269
283
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( ) ) ;
284
+ if get_arg_flag_value ( "--emit" ) . unwrap_or_default ( ) . split ( ',' ) . any ( |e| e == "dep-info" ) {
285
+ // Create a stub .d file to stop Cargo from "rebuilding" the crate:
286
+ // https://github.com/rust-lang/miri/issues/1724#issuecomment-787115693
287
+ // As we store a JSON file instead of building the crate here, an empty file is fine.
288
+ let dep_info_name = format ! (
289
+ "{}/{}{}.d" ,
290
+ get_arg_flag_value( "--out-dir" ) . unwrap( ) ,
291
+ get_arg_flag_value( "--crate-name" ) . unwrap( ) ,
292
+ get_arg_flag_value( "extra-filename" ) . unwrap_or_default( ) ,
293
+ ) ;
294
+ if verbose > 0 {
295
+ eprintln ! ( "[cargo-miri rustc] writing stub dep-info to `{dep_info_name}`" ) ;
296
+ }
297
+ File :: create ( dep_info_name) . expect ( "failed to create fake .d file" ) ;
276
298
}
277
- File :: create ( dep_info_name) . expect ( "failed to create fake .d file" ) ;
278
299
279
- let filename = out_filename ( "" , "" ) ;
280
- if verbose > 0 {
281
- eprintln ! ( "[cargo-miri rustc] writing run info to `{}`" , filename. display( ) ) ;
300
+ for filename in out_filenames ( ) {
301
+ if verbose > 0 {
302
+ eprintln ! ( "[cargo-miri rustc] writing run info to `{}`" , filename. display( ) ) ;
303
+ }
304
+ info. store ( & filename) ;
282
305
}
283
- 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" ) ) ;
288
306
} ;
289
307
290
308
let runnable_crate = !info_query && is_runnable_crate ( ) ;
@@ -323,11 +341,14 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
323
341
324
342
// Alter the `-o` parameter so that it does not overwrite the JSON file we stored above.
325
343
let mut args = env. args ;
344
+ let mut out_filename = None ;
326
345
for i in 0 ..args. len ( ) {
327
346
if args[ i] == "-o" {
347
+ out_filename = Some ( args[ i + 1 ] . clone ( ) ) ;
328
348
args[ i + 1 ] . push_str ( ".miri" ) ;
329
349
}
330
350
}
351
+ let out_filename = out_filename. expect ( "rustdoc must pass `-o`" ) ;
331
352
332
353
cmd. args ( & args) ;
333
354
cmd. env ( "MIRI_BE_RUSTC" , "target" ) ;
@@ -340,7 +361,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
340
361
eprintln ! ( "[cargo-miri rustc inside rustdoc] going to run:\n {cmd:?}" ) ;
341
362
}
342
363
343
- exec_with_pipe ( cmd, & env. stdin , format ! ( "{}.stdin" , out_filename ( "" , "" ) . display ( ) ) ) ;
364
+ exec_with_pipe ( cmd, & env. stdin , format ! ( "{out_filename }.stdin" ) ) ;
344
365
}
345
366
346
367
return ;
@@ -422,15 +443,12 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
422
443
// Create a stub .rlib file if "link" was requested by cargo.
423
444
// This is necessary to prevent cargo from doing rebuilds all the time.
424
445
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" ) ;
446
+ for filename in out_filenames ( ) {
447
+ if verbose > 0 {
448
+ eprintln ! ( "[cargo-miri rustc] creating fake lib file at `{}`" , filename. display( ) ) ;
449
+ }
450
+ File :: create ( filename) . expect ( "failed to create fake lib file" ) ;
451
+ }
434
452
}
435
453
436
454
debug_cmd ( "[cargo-miri rustc]" , verbose, & cmd) ;
0 commit comments