Skip to content

Commit 09f30ca

Browse files
committed
cargo miri: make sure we see the same sysroot for rustc and miri
1 parent 2448e9d commit 09f30ca

File tree

1 file changed

+37
-1
lines changed

1 file changed

+37
-1
lines changed

src/bin/cargo-miri.rs

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,39 @@ fn list_targets() -> impl Iterator<Item=cargo_metadata::Target> {
119119
package.targets.into_iter()
120120
}
121121

122+
/// Make sure that the `miri` and `rustc` binary are from the same sysroot.
123+
/// This can be violated e.g. when miri is locally built and installed with a different
124+
/// toolchain than what is used when `cargo miri` is run.
125+
fn test_sysroot_consistency() {
126+
fn get_sysroot(mut cmd: Command) -> PathBuf {
127+
let out = cmd.arg("--print").arg("sysroot")
128+
.env_remove("MIRI_SYSROOT") // We want to test their "native" sysroot, not the manually set one
129+
.output().expect("Failed to run rustc to get sysroot info");
130+
assert!(out.status.success(), "Bad statuc code when getting sysroot info");
131+
let sysroot = out.stdout.lines().nth(0)
132+
.expect("didn't get at least one line for the sysroot").unwrap();
133+
PathBuf::from(sysroot).canonicalize()
134+
.expect("Failed to canonicalize sysroot")
135+
}
136+
137+
let rustc_sysroot = get_sysroot(Command::new("rustc"));
138+
let miri_sysroot = {
139+
let mut path = std::env::current_exe().expect("current executable path invalid");
140+
path.set_file_name("miri");
141+
get_sysroot(Command::new(path))
142+
};
143+
144+
if rustc_sysroot != miri_sysroot {
145+
show_error(format!(
146+
"miri was built for a different sysroot than the rustc in your current toolchain.\n\
147+
Make sure you use the same toolchain to run miri that you used to build it!\n\
148+
rustc sysroot: `{}`\n\
149+
miri sysroot: `{}`",
150+
rustc_sysroot.display(), miri_sysroot.display()
151+
));
152+
}
153+
}
154+
122155
fn xargo_version() -> Option<(u32, u32, u32)> {
123156
let out = Command::new("xargo").arg("--version").output().ok()?;
124157
if !out.status.success() {
@@ -269,7 +302,7 @@ path = "lib.rs"
269302
if print_env {
270303
println!("MIRI_SYSROOT={}", sysroot.display());
271304
} else if !ask_user {
272-
println!("A libstd for Miri is now available in `{}`", sysroot.display());
305+
println!("A libstd for Miri is now available in `{}`.", sysroot.display());
273306
}
274307
}
275308

@@ -313,6 +346,9 @@ fn in_cargo_miri() {
313346
};
314347
let verbose = has_arg_flag("-v");
315348

349+
// Some basic sanity checks
350+
test_sysroot_consistency();
351+
316352
// We always setup.
317353
let ask = subcommand != MiriCommand::Setup;
318354
setup(ask);

0 commit comments

Comments
 (0)