Auto merge of #1779 - RalfJung:cargo-miri-xargo, r=RalfJung
fix MIRI_BE_RUSTC value during sysroot build `@hyd-dev` pointed out that `MIRI_BE_RUSTC` is set to an incorrect value during the xargo sysroot build. This fixes that.
This commit is contained in:
commit
74ffda2dd7
@ -283,16 +283,17 @@ Moreover, Miri recognizes some environment variables:
|
||||
architecture to test against. `miri` and `cargo miri` accept the `--target`
|
||||
flag for the same purpose.
|
||||
|
||||
The following environment variables are internal, but used to communicate between
|
||||
different Miri binaries, and as such worth documenting:
|
||||
The following environment variables are *internal* and must not be used by
|
||||
anyone but Miri itself. They are used to communicate between different Miri
|
||||
binaries, and as such worth documenting:
|
||||
|
||||
* `MIRI_BE_RUSTC` can be set to `host` or `target`. It tells the Miri driver to
|
||||
actually not interpret the code but compile it like rustc would. With `target`, Miri sets
|
||||
some compiler flags to prepare the code for interpretation; with `host`, this is not done.
|
||||
This environment variable is useful to be sure that the compiled `rlib`s are compatible
|
||||
with Miri.
|
||||
When set while running `cargo-miri`, it indicates that we are part of a sysroot
|
||||
build (for which some crates need special treatment).
|
||||
* `MIRI_CALLED_FROM_XARGO` is set during the Miri-induced `xargo` sysroot build,
|
||||
which will re-invoke `cargo-miri` as the `rustc` to use for this build.
|
||||
* `MIRI_CALLED_FROM_RUSTDOC` when set to any value tells `cargo-miri` that it is
|
||||
running as a child process of `rustdoc`, which invokes it twice for each doc-test
|
||||
and requires special treatment, most notably a check-only build before interpretation.
|
||||
|
@ -413,14 +413,14 @@ path = "lib.rs"
|
||||
// for target crates.
|
||||
// We set ourselves (`cargo-miri`) instead of Miri directly to be able to patch the flags
|
||||
// for `libpanic_abort` (usually this is done by bootstrap but we have to do it ourselves).
|
||||
// The `MIRI_BE_RUSTC` will mean we dispatch to `phase_setup_rustc`.
|
||||
// The `MIRI_CALLED_FROM_XARGO` will mean we dispatch to `phase_setup_rustc`.
|
||||
let cargo_miri_path = std::env::current_exe().expect("current executable path invalid");
|
||||
if env::var_os("RUSTC_STAGE").is_some() {
|
||||
command.env("RUSTC_REAL", &cargo_miri_path);
|
||||
} else {
|
||||
command.env("RUSTC", &cargo_miri_path);
|
||||
}
|
||||
command.env("MIRI_BE_RUSTC", "target");
|
||||
command.env("MIRI_CALLED_FROM_XARGO", "1");
|
||||
// Make sure there are no other wrappers or flags getting in our way
|
||||
// (Cc https://github.com/rust-lang/miri/issues/1421).
|
||||
// This is consistent with normal `cargo build` that does not apply `RUSTFLAGS`
|
||||
@ -450,21 +450,6 @@ path = "lib.rs"
|
||||
}
|
||||
}
|
||||
|
||||
fn phase_setup_rustc(args: env::Args) {
|
||||
// Mostly we just forward everything.
|
||||
// `MIRI_BE_RUST` is already set.
|
||||
let mut cmd = miri();
|
||||
cmd.args(args);
|
||||
|
||||
// Patch the panic runtime for `libpanic_abort` (mirroring what bootstrap usually does).
|
||||
if get_arg_flag_value("--crate-name").as_deref() == Some("panic_abort") {
|
||||
cmd.arg("-C").arg("panic=abort");
|
||||
}
|
||||
|
||||
// Run it!
|
||||
exec(cmd);
|
||||
}
|
||||
|
||||
fn phase_cargo_miri(mut args: env::Args) {
|
||||
// Check for version and help flags even when invoked as `cargo-miri`.
|
||||
if has_arg_flag("--help") || has_arg_flag("-h") {
|
||||
@ -598,7 +583,17 @@ fn phase_cargo_miri(mut args: env::Args) {
|
||||
exec(cmd)
|
||||
}
|
||||
|
||||
fn phase_cargo_rustc(mut args: env::Args) {
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
enum RustcPhase {
|
||||
/// `rustc` called via `xargo` for sysroot build.
|
||||
Setup,
|
||||
/// `rustc` called by `cargo` for regular build.
|
||||
Build,
|
||||
/// `rustc` called by `rustdoc` for doctest.
|
||||
Rustdoc,
|
||||
}
|
||||
|
||||
fn phase_rustc(mut args: env::Args, phase: RustcPhase) {
|
||||
/// Determines if we are being invoked (as rustc) to build a crate for
|
||||
/// the "target" architecture, in contrast to the "host" architecture.
|
||||
/// Host crates are for build scripts and proc macros and still need to
|
||||
@ -644,7 +639,7 @@ fn phase_cargo_rustc(mut args: env::Args) {
|
||||
|
||||
let verbose = std::env::var_os("MIRI_VERBOSE").is_some();
|
||||
let target_crate = is_target_crate();
|
||||
let print = get_arg_flag_value("--print").is_some(); // whether this is cargo passing `--print` to get some infos
|
||||
let print = get_arg_flag_value("--print").is_some() || has_arg_flag("-vV"); // whether this is cargo/xargo invoking rustc to get some infos
|
||||
|
||||
let store_json = |info: CrateRunInfo| {
|
||||
// Create a stub .d file to stop Cargo from "rebuilding" the crate:
|
||||
@ -669,7 +664,8 @@ fn phase_cargo_rustc(mut args: env::Args) {
|
||||
let runnable_crate = !print && is_runnable_crate();
|
||||
|
||||
if runnable_crate && target_crate {
|
||||
let inside_rustdoc = env::var_os("MIRI_CALLED_FROM_RUSTDOC").is_some();
|
||||
assert!(phase != RustcPhase::Setup, "there should be no interpretation during sysroot build");
|
||||
let inside_rustdoc = phase == RustcPhase::Rustdoc;
|
||||
// This is the binary or test crate that we want to interpret under Miri.
|
||||
// But we cannot run it here, as cargo invoked us as a compiler -- our stdin and stdout are not
|
||||
// like we want them.
|
||||
@ -749,8 +745,15 @@ fn phase_cargo_rustc(mut args: env::Args) {
|
||||
}
|
||||
}
|
||||
|
||||
// Use our custom sysroot.
|
||||
forward_miri_sysroot(&mut cmd);
|
||||
// Use our custom sysroot (but not if that is what we are currently building).
|
||||
if phase != RustcPhase::Setup {
|
||||
forward_miri_sysroot(&mut cmd);
|
||||
}
|
||||
|
||||
// During setup, patch the panic runtime for `libpanic_abort` (mirroring what bootstrap usually does).
|
||||
if phase == RustcPhase::Setup && get_arg_flag_value("--crate-name").as_deref() == Some("panic_abort") {
|
||||
cmd.arg("-C").arg("panic=abort");
|
||||
}
|
||||
} else {
|
||||
// For host crates or when we are printing, just forward everything.
|
||||
cmd.args(args);
|
||||
@ -783,7 +786,15 @@ fn phase_cargo_rustc(mut args: env::Args) {
|
||||
}
|
||||
}
|
||||
|
||||
fn phase_cargo_runner(binary: &Path, binary_args: env::Args) {
|
||||
#[derive(Debug, Copy, Clone, PartialEq)]
|
||||
enum RunnerPhase {
|
||||
/// `cargo` is running a binary
|
||||
Cargo,
|
||||
/// `rustdoc` is running a binary
|
||||
Rustdoc,
|
||||
}
|
||||
|
||||
fn phase_runner(binary: &Path, binary_args: env::Args, phase: RunnerPhase) {
|
||||
let verbose = std::env::var_os("MIRI_VERBOSE").is_some();
|
||||
|
||||
let file = File::open(&binary)
|
||||
@ -840,8 +851,8 @@ fn phase_cargo_runner(binary: &Path, binary_args: env::Args) {
|
||||
cmd.arg(arg);
|
||||
}
|
||||
}
|
||||
if env::var_os("MIRI_CALLED_FROM_RUSTDOC").is_none() {
|
||||
// Set sysroot (if we are inside rustdoc, we already did that in `phase_cargo_rustdoc`).
|
||||
// Set sysroot (if we are inside rustdoc, we already did that in `phase_cargo_rustdoc`).
|
||||
if phase != RunnerPhase::Rustdoc {
|
||||
forward_miri_sysroot(&mut cmd);
|
||||
}
|
||||
// Respect `MIRIFLAGS`.
|
||||
@ -869,14 +880,17 @@ fn phase_cargo_runner(binary: &Path, binary_args: env::Args) {
|
||||
eprintln!("[cargo-miri runner] {:?}", cmd);
|
||||
}
|
||||
|
||||
if std::env::var_os("MIRI_CALLED_FROM_RUSTDOC").is_some() {
|
||||
exec_with_pipe(cmd, &info.stdin)
|
||||
} else {
|
||||
exec(cmd)
|
||||
match phase {
|
||||
RunnerPhase::Rustdoc => {
|
||||
exec_with_pipe(cmd, &info.stdin)
|
||||
}
|
||||
RunnerPhase::Cargo => {
|
||||
exec(cmd)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn phase_cargo_rustdoc(fst_arg: &str, mut args: env::Args) {
|
||||
fn phase_rustdoc(fst_arg: &str, mut args: env::Args) {
|
||||
let verbose = std::env::var_os("MIRI_VERBOSE").is_some();
|
||||
|
||||
// phase_cargo_miri sets the RUSTDOC env var to ourselves, so we can't use that here;
|
||||
@ -950,15 +964,14 @@ fn main() {
|
||||
args.next().unwrap();
|
||||
|
||||
// Dispatch running as part of sysroot compilation.
|
||||
if env::var_os("MIRI_BE_RUSTC").is_some() {
|
||||
phase_setup_rustc(args);
|
||||
if env::var_os("MIRI_CALLED_FROM_XARGO").is_some() {
|
||||
phase_rustc(args, RustcPhase::Setup);
|
||||
return;
|
||||
}
|
||||
|
||||
// The way rustdoc invokes rustc is indistuingishable from the way cargo invokes rustdoc by the
|
||||
// arguments alone. `phase_cargo_rustdoc` sets this environment variable to let us disambiguate.
|
||||
let invoked_by_rustdoc = env::var_os("MIRI_CALLED_FROM_RUSTDOC").is_some();
|
||||
if invoked_by_rustdoc {
|
||||
if env::var_os("MIRI_CALLED_FROM_RUSTDOC").is_some() {
|
||||
// ...however, we then also see this variable when rustdoc invokes us as the testrunner!
|
||||
// The runner is invoked as `$runtool ($runtool-arg)* output_file`;
|
||||
// since we don't specify any runtool-args, and rustdoc supplies multiple arguments to
|
||||
@ -967,12 +980,12 @@ fn main() {
|
||||
let arg = args.next().unwrap();
|
||||
let binary = Path::new(&arg);
|
||||
if binary.exists() {
|
||||
phase_cargo_runner(binary, args);
|
||||
phase_runner(binary, args, RunnerPhase::Rustdoc);
|
||||
} else {
|
||||
show_error(format!("`cargo-miri` called with non-existing path argument `{}` in rustdoc mode; please invoke this binary through `cargo miri`", arg));
|
||||
}
|
||||
} else {
|
||||
phase_cargo_rustc(args);
|
||||
phase_rustc(args, RustcPhase::Rustdoc);
|
||||
}
|
||||
|
||||
return;
|
||||
@ -988,7 +1001,7 @@ fn main() {
|
||||
// On top of that, we are also called as RUSTDOC, but that is just a stub currently.
|
||||
match args.next().as_deref() {
|
||||
Some("miri") => phase_cargo_miri(args),
|
||||
Some("rustc") => phase_cargo_rustc(args),
|
||||
Some("rustc") => phase_rustc(args, RustcPhase::Build),
|
||||
Some(arg) => {
|
||||
// We have to distinguish the "runner" and "rustdoc" cases.
|
||||
// As runner, the first argument is the binary (a file that should exist, with an absolute path);
|
||||
@ -996,9 +1009,9 @@ fn main() {
|
||||
let binary = Path::new(arg);
|
||||
if binary.exists() {
|
||||
assert!(!arg.starts_with("--")); // not a flag
|
||||
phase_cargo_runner(binary, args);
|
||||
phase_runner(binary, args, RunnerPhase::Cargo);
|
||||
} else if arg.starts_with("--") {
|
||||
phase_cargo_rustdoc(arg, args);
|
||||
phase_rustdoc(arg, args);
|
||||
} else {
|
||||
show_error(format!("`cargo-miri` called with unexpected first argument `{}`; please only invoke this binary through `cargo miri`", arg));
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user