Skip to content

Commit 6fb2e9a

Browse files
committed
cargo-miri: use rustc to determine the output filename
1 parent 4f051a6 commit 6fb2e9a

File tree

1 file changed

+43
-32
lines changed

1 file changed

+43
-32
lines changed

cargo-miri/src/phases.rs

Lines changed: 43 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -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 a `-C` flag pass as `-C extra-filename=...`, but the prefix seems
251+
// unique 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.split('\n').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()
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

Comments
 (0)