Skip to content

Commit e132cd6

Browse files
authored
Rollup merge of #106229 - RalfJung:miri, r=RalfJung
update Miri Main PRs: - rust-lang#2741 - rust-lang#2744 This should help quite a bit with Miri support for less common targets. :)
2 parents 79b6e12 + 61a933f commit e132cd6

23 files changed

+340
-239
lines changed

Cargo.lock

+87-67
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cargo-miri/Cargo.lock

+35-34
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

cargo-miri/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ directories = "4"
1818
rustc_version = "0.4"
1919
serde_json = "1.0.40"
2020
cargo_metadata = "0.15.0"
21-
rustc-build-sysroot = "0.4"
21+
rustc-build-sysroot = "0.4.1"
2222

2323
# A noop dependency that changes in the Rust repository, it's a bit of a hack.
2424
# See the `src/tools/rustc-workspace-hack/README.md` file in `rust-lang/rust`

cargo-miri/src/phases.rs

+58-40
Original file line numberDiff line numberDiff line change
@@ -236,22 +236,36 @@ 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 {
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)]
252243
} 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()
255269
}
256270
}
257271

@@ -267,24 +281,28 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
267281
let info_query = get_arg_flag_value("--print").is_some() || has_arg_flag("-vV");
268282

269283
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");
276298
}
277-
File::create(dep_info_name).expect("failed to create fake .d file");
278299

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);
282305
}
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"));
288306
};
289307

290308
let runnable_crate = !info_query && is_runnable_crate();
@@ -323,11 +341,14 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
323341

324342
// Alter the `-o` parameter so that it does not overwrite the JSON file we stored above.
325343
let mut args = env.args;
344+
let mut out_filename = None;
326345
for i in 0..args.len() {
327346
if args[i] == "-o" {
347+
out_filename = Some(args[i + 1].clone());
328348
args[i + 1].push_str(".miri");
329349
}
330350
}
351+
let out_filename = out_filename.expect("rustdoc must pass `-o`");
331352

332353
cmd.args(&args);
333354
cmd.env("MIRI_BE_RUSTC", "target");
@@ -340,7 +361,7 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
340361
eprintln!("[cargo-miri rustc inside rustdoc] going to run:\n{cmd:?}");
341362
}
342363

343-
exec_with_pipe(cmd, &env.stdin, format!("{}.stdin", out_filename("", "").display()));
364+
exec_with_pipe(cmd, &env.stdin, format!("{out_filename}.stdin"));
344365
}
345366

346367
return;
@@ -422,15 +443,12 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
422443
// Create a stub .rlib file if "link" was requested by cargo.
423444
// This is necessary to prevent cargo from doing rebuilds all the time.
424445
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+
}
434452
}
435453

436454
debug_cmd("[cargo-miri rustc]", verbose, &cmd);

cargo-miri/src/setup.rs

+5-3
Original file line numberDiff line numberDiff line change
@@ -137,9 +137,11 @@ pub fn setup(subcommand: &MiriCommand, target: &str, rustc_version: &VersionMeta
137137
.rustflags(rustflags)
138138
.cargo(cargo_cmd)
139139
.build_from_source(&rust_src)
140-
.unwrap_or_else(|_| {
141-
if only_setup {
142-
show_error!("failed to build sysroot, see error details above")
140+
.unwrap_or_else(|err| {
141+
if print_sysroot {
142+
show_error!("failed to build sysroot")
143+
} else if only_setup {
144+
show_error!("failed to build sysroot: {err:?}")
143145
} else {
144146
show_error!(
145147
"failed to build sysroot; run `cargo miri setup` to see the error details"

ci.sh

+2-1
Original file line numberDiff line numberDiff line change
@@ -108,8 +108,9 @@ case $HOST_TARGET in
108108
MIRI_TEST_TARGET=i686-pc-windows-msvc run_tests
109109
MIRI_TEST_TARGET=x86_64-unknown-freebsd run_tests_minimal hello integer vec panic/panic concurrency/simple atomic data_race env/var
110110
MIRI_TEST_TARGET=aarch64-linux-android run_tests_minimal hello integer vec panic/panic
111-
MIRI_TEST_TARGET=wasm32-wasi MIRI_NO_STD=1 run_tests_minimal no_std # supports std but miri doesn't support it
111+
MIRI_TEST_TARGET=wasm32-wasi run_tests_minimal no_std integer
112112
MIRI_TEST_TARGET=thumbv7em-none-eabihf MIRI_NO_STD=1 run_tests_minimal no_std # no_std embedded architecture
113+
MIRI_TEST_TARGET=tests/avr.json MIRI_NO_STD=1 run_tests_minimal no_std # JSON target file
113114
;;
114115
x86_64-apple-darwin)
115116
MIRI_TEST_TARGET=mips64-unknown-linux-gnuabi64 run_tests # big-endian architecture

0 commit comments

Comments
 (0)