Skip to content

Commit 6df153c

Browse files
committed
set --sysroot outside the driver rather than messing with the arguments passed to the driver
1 parent 4329cc6 commit 6df153c

File tree

5 files changed

+29
-32
lines changed

5 files changed

+29
-32
lines changed

README.md

+2-3
Original file line numberDiff line numberDiff line change
@@ -464,10 +464,9 @@ Moreover, Miri recognizes some environment variables:
464464
standard library that it will build and use for interpretation. This directory
465465
must point to the `library` subdirectory of a `rust-lang/rust` repository
466466
checkout.
467-
* `MIRI_SYSROOT` (recognized by `cargo miri` and the Miri driver) indicates the sysroot to use. When
467+
* `MIRI_SYSROOT` (recognized by `cargo miri` and the test suite) indicates the sysroot to use. When
468468
using `cargo miri`, this skips the automatic setup -- only set this if you do not want to use the
469-
automatically created sysroot. For directly invoking the Miri driver, this variable (or a
470-
`--sysroot` flag) is mandatory. When invoking `cargo miri setup`, this indicates where the sysroot
469+
automatically created sysroot. When invoking `cargo miri setup`, this indicates where the sysroot
471470
will be put.
472471
* `MIRI_TEST_TARGET` (recognized by the test suite and the `./miri` script) indicates which target
473472
architecture to test against. `miri` and `cargo miri` accept the `--target` flag for the same

cargo-miri/src/phases.rs

+10-2
Original file line numberDiff line numberDiff line change
@@ -168,8 +168,6 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
168168
// Forward all further arguments (not consumed by `ArgSplitFlagValue`) to cargo.
169169
cmd.args(args);
170170

171-
// Let it know where the Miri sysroot lives.
172-
cmd.env("MIRI_SYSROOT", miri_sysroot);
173171
// Set `RUSTC_WRAPPER` to ourselves. Cargo will prepend that binary to its usual invocation,
174172
// i.e., the first argument is `rustc` -- which is what we use in `main` to distinguish
175173
// the two codepaths. (That extra argument is why we prefer this over setting `RUSTC`.)
@@ -204,6 +202,8 @@ pub fn phase_cargo_miri(mut args: impl Iterator<Item = String>) {
204202
// Set rustdoc to us as well, so we can run doctests.
205203
cmd.env("RUSTDOC", &cargo_miri_path);
206204

205+
// Forward some crucial information to our own re-invocations.
206+
cmd.env("MIRI_SYSROOT", miri_sysroot);
207207
cmd.env("MIRI_LOCAL_CRATES", local_crates(&metadata));
208208
if verbose > 0 {
209209
cmd.env("MIRI_VERBOSE", verbose.to_string()); // This makes the other phases verbose.
@@ -393,6 +393,8 @@ pub fn phase_rustc(mut args: impl Iterator<Item = String>, phase: RustcPhase) {
393393
// Arguments are treated very differently depending on whether this crate is
394394
// for interpretation by Miri, or for use by a build script / proc macro.
395395
if !info_query && target_crate {
396+
// Set the sysroot.
397+
cmd.arg("--sysroot").arg(env::var_os("MIRI_SYSROOT").unwrap());
396398
// Forward arguments, but remove "link" from "--emit" to make this a check-only build.
397399
let emit_flag = "--emit";
398400
while let Some(arg) = args.next() {
@@ -531,6 +533,12 @@ pub fn phase_runner(mut binary_args: impl Iterator<Item = String>, phase: Runner
531533
cmd.env(name, val);
532534
}
533535

536+
if phase != RunnerPhase::Rustdoc {
537+
// Set the sysroot. Not necessary in rustdoc, where we already set the sysroot when invoking
538+
// rustdoc itself, which will forward that flag when invoking rustc (i.e., us), so the flag
539+
// is present in `info.args`.
540+
cmd.arg("--sysroot").arg(env::var_os("MIRI_SYSROOT").unwrap());
541+
}
534542
// Forward rustc arguments.
535543
// We need to patch "--extern" filenames because we forced a check-only
536544
// build without cargo knowing about that: replace `.rlib` suffix by

miri-script/src/commands.rs

+10-8
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use std::env;
22
use std::ffi::OsString;
33
use std::io::Write;
44
use std::ops::Not;
5+
use std::path::PathBuf;
56
use std::process;
67
use std::thread;
78
use std::time;
@@ -20,10 +21,11 @@ const JOSH_FILTER: &str =
2021
const JOSH_PORT: &str = "42042";
2122

2223
impl MiriEnv {
23-
fn build_miri_sysroot(&mut self, quiet: bool) -> Result<()> {
24-
if self.sh.var("MIRI_SYSROOT").is_ok() {
24+
/// Returns the location of the sysroot.
25+
fn build_miri_sysroot(&mut self, quiet: bool) -> Result<PathBuf> {
26+
if let Some(miri_sysroot) = self.sh.var_os("MIRI_SYSROOT") {
2527
// Sysroot already set, use that.
26-
return Ok(());
28+
return Ok(miri_sysroot.into());
2729
}
2830
let manifest_path = path!(self.miri_dir / "cargo-miri" / "Cargo.toml");
2931
let Self { toolchain, cargo_extra_flags, .. } = &self;
@@ -57,8 +59,8 @@ impl MiriEnv {
5759
.with_context(|| "`cargo miri setup` failed")?;
5860
panic!("`cargo miri setup` didn't fail again the 2nd time?");
5961
};
60-
self.sh.set_var("MIRI_SYSROOT", output);
61-
Ok(())
62+
self.sh.set_var("MIRI_SYSROOT", &output);
63+
Ok(output.into())
6264
}
6365
}
6466

@@ -502,7 +504,7 @@ impl Command {
502504
flags.iter().take_while(|arg| *arg != "--").any(|arg| *arg == "--edition");
503505

504506
// Prepare a sysroot.
505-
e.build_miri_sysroot(/* quiet */ true)?;
507+
let miri_sysroot = e.build_miri_sysroot(/* quiet */ true)?;
506508

507509
// Then run the actual command.
508510
let miri_manifest = path!(e.miri_dir / "Cargo.toml");
@@ -514,12 +516,12 @@ impl Command {
514516
if dep {
515517
cmd!(
516518
e.sh,
517-
"cargo +{toolchain} --quiet test {extra_flags...} --manifest-path {miri_manifest} --test ui -- --miri-run-dep-mode {miri_flags...} {edition_flags...} {flags...}"
519+
"cargo +{toolchain} --quiet test {extra_flags...} --manifest-path {miri_manifest} --test ui -- --miri-run-dep-mode --sysroot {miri_sysroot} {miri_flags...} {edition_flags...} {flags...}"
518520
).quiet().run()?;
519521
} else {
520522
cmd!(
521523
e.sh,
522-
"cargo +{toolchain} --quiet run {extra_flags...} --manifest-path {miri_manifest} -- {miri_flags...} {edition_flags...} {flags...}"
524+
"cargo +{toolchain} --quiet run {extra_flags...} --manifest-path {miri_manifest} -- --sysroot {miri_sysroot} {miri_flags...} {edition_flags...} {flags...}"
523525
).quiet().run()?;
524526
}
525527
Ok(())

src/bin/miri.rs

-19
Original file line numberDiff line numberDiff line change
@@ -271,25 +271,6 @@ fn run_compiler(
271271
callbacks: &mut (dyn rustc_driver::Callbacks + Send),
272272
using_internal_features: std::sync::Arc<std::sync::atomic::AtomicBool>,
273273
) -> ! {
274-
if target_crate {
275-
// Miri needs a custom sysroot for target crates.
276-
// If no `--sysroot` is given, the `MIRI_SYSROOT` env var is consulted to find where
277-
// that sysroot lives, and that is passed to rustc.
278-
let sysroot_flag = "--sysroot";
279-
if !args.iter().any(|e| e == sysroot_flag) {
280-
// Using the built-in default here would be plain wrong, so we *require*
281-
// the env var to make sure things make sense.
282-
let miri_sysroot = env::var("MIRI_SYSROOT").unwrap_or_else(|_| {
283-
show_error!(
284-
"Miri was invoked in 'target' mode without `MIRI_SYSROOT` or `--sysroot` being set"
285-
)
286-
});
287-
288-
args.push(sysroot_flag.to_owned());
289-
args.push(miri_sysroot);
290-
}
291-
}
292-
293274
// Don't insert `MIRI_DEFAULT_ARGS`, in particular, `--cfg=miri`, if we are building
294275
// a "host" crate. That may cause procedural macros (and probably build scripts) to
295276
// depend on Miri-only symbols, such as `miri_resolve_frame`:

tests/ui.rs

+7
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,13 @@ fn test_config(target: &str, path: &str, mode: Mode, with_dependencies: bool) ->
6060
program.program = miri_path();
6161

6262
// Add some flags we always want.
63+
program.args.push(
64+
format!(
65+
"--sysroot={}",
66+
env::var("MIRI_SYSROOT").expect("MIRI_SYSROOT must be set to run the ui test suite")
67+
)
68+
.into(),
69+
);
6370
program.args.push("-Dwarnings".into());
6471
program.args.push("-Dunused".into());
6572
program.args.push("-Ainternal_features".into());

0 commit comments

Comments
 (0)