@@ -236,22 +236,44 @@ 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
269
+ . lines ( )
270
+ . filter ( |l| !l. is_empty ( ) )
271
+ . map ( |l| {
272
+ let mut p = path. clone ( ) ;
273
+ p. push ( l) ;
274
+ p
275
+ } )
276
+ . collect ( )
255
277
}
256
278
}
257
279
@@ -267,24 +289,28 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
267
289
let info_query = get_arg_flag_value ( "--print" ) . is_some ( ) || has_arg_flag ( "-vV" ) ;
268
290
269
291
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( ) ) ;
292
+ if get_arg_flag_value ( "--emit" ) . unwrap_or_default ( ) . split ( ',' ) . any ( |e| e == "dep-info" ) {
293
+ // Create a stub .d file to stop Cargo from "rebuilding" the crate:
294
+ // https://github.com/rust-lang/miri/issues/1724#issuecomment-787115693
295
+ // As we store a JSON file instead of building the crate here, an empty file is fine.
296
+ let dep_info_name = format ! (
297
+ "{}/{}{}.d" ,
298
+ get_arg_flag_value( "--out-dir" ) . unwrap( ) ,
299
+ get_arg_flag_value( "--crate-name" ) . unwrap( ) ,
300
+ get_arg_flag_value( "extra-filename" ) . unwrap_or_default( ) ,
301
+ ) ;
302
+ if verbose > 0 {
303
+ eprintln ! ( "[cargo-miri rustc] writing stub dep-info to `{dep_info_name}`" ) ;
304
+ }
305
+ File :: create ( dep_info_name) . expect ( "failed to create fake .d file" ) ;
276
306
}
277
- File :: create ( dep_info_name) . expect ( "failed to create fake .d file" ) ;
278
307
279
- let filename = out_filename ( "" , "" ) ;
280
- if verbose > 0 {
281
- eprintln ! ( "[cargo-miri rustc] writing run info to `{}`" , filename. display( ) ) ;
308
+ for filename in out_filenames ( ) {
309
+ if verbose > 0 {
310
+ eprintln ! ( "[cargo-miri rustc] writing run info to `{}`" , filename. display( ) ) ;
311
+ }
312
+ info. store ( & filename) ;
282
313
}
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
314
} ;
289
315
290
316
let runnable_crate = !info_query && is_runnable_crate ( ) ;
@@ -323,11 +349,14 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
323
349
324
350
// Alter the `-o` parameter so that it does not overwrite the JSON file we stored above.
325
351
let mut args = env. args ;
352
+ let mut out_filename = None ;
326
353
for i in 0 ..args. len ( ) {
327
354
if args[ i] == "-o" {
355
+ out_filename = Some ( args[ i + 1 ] . clone ( ) ) ;
328
356
args[ i + 1 ] . push_str ( ".miri" ) ;
329
357
}
330
358
}
359
+ let out_filename = out_filename. expect ( "rustdoc must pass `-o`" ) ;
331
360
332
361
cmd. args ( & args) ;
333
362
cmd. env ( "MIRI_BE_RUSTC" , "target" ) ;
@@ -340,7 +369,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
340
369
eprintln ! ( "[cargo-miri rustc inside rustdoc] going to run:\n {cmd:?}" ) ;
341
370
}
342
371
343
- exec_with_pipe ( cmd, & env. stdin , format ! ( "{}.stdin" , out_filename ( "" , "" ) . display ( ) ) ) ;
372
+ exec_with_pipe ( cmd, & env. stdin , format ! ( "{out_filename }.stdin" ) ) ;
344
373
}
345
374
346
375
return ;
@@ -422,15 +451,12 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
422
451
// Create a stub .rlib file if "link" was requested by cargo.
423
452
// This is necessary to prevent cargo from doing rebuilds all the time.
424
453
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" ) ;
454
+ for filename in out_filenames ( ) {
455
+ if verbose > 0 {
456
+ eprintln ! ( "[cargo-miri rustc] creating fake lib file at `{}`" , filename. display( ) ) ;
457
+ }
458
+ File :: create ( filename) . expect ( "failed to create fake lib file" ) ;
459
+ }
434
460
}
435
461
436
462
debug_cmd ( "[cargo-miri rustc]" , verbose, & cmd) ;
0 commit comments