Skip to content

Commit

Permalink
Rollup merge of rust-lang#63162 - RalfJung:miri-xargo, r=alexcrichton
Browse files Browse the repository at this point in the history
Miri tests: use xargo to build separate libstd

This uses `cargo miri setup` to prepare the libstd that is used for testing Miri, instead of adjusting the entire bootstrap process to make sure the libstd that already gets built is fit for Miri.

The issue with our current approach is that with `test-miri = true`, libstd and the test suite get built with `--cfg miri`, which e.g. means hashbrown uses no SIMD, and not all things are tested. Such global side-effects seem like footguns waiting to go off.

On the other hand, the new approach means we install xargo as a side-effect of doing `./x.py test src/tools/miri`, which might be surprising, and we also both have to build xargo and another libstd which costs some extra time. Not sure if the tools builders have enough time budget for that. Maybe there is a way to cache xargo?

We have to first first land rust-lang/miri#870 in Miri and then update this PR to include that change (also to get CI to test Miri before bors), but I wanted to get the review started here.

Cc @oli-obk (for Miri) @alexcrichton (for CI) @Mark-Simulacrum (for bootstrap)

Fixes rust-lang#61833, fixes rust-lang#63219
  • Loading branch information
Centril authored Aug 8, 2019
2 parents 2d1a551 + e6be1d7 commit fea43aa
Show file tree
Hide file tree
Showing 10 changed files with 86 additions and 55 deletions.
4 changes: 0 additions & 4 deletions config.toml.example
Original file line number Diff line number Diff line change
Expand Up @@ -368,10 +368,6 @@
# When creating source tarballs whether or not to create a source tarball.
#dist-src = false

# Whether to also run the Miri tests suite when running tests.
# As a side-effect also generates MIR for all libraries.
#test-miri = false

# After building or testing extended tools (e.g. clippy and rustfmt), append the
# result (broken, compiling, testing) into this JSON file.
#save-toolstates = "/path/to/toolstates.json"
Expand Down
21 changes: 5 additions & 16 deletions src/bootstrap/bin/rustc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -143,8 +143,11 @@ fn main() {

if let Some(target) = target {
// The stage0 compiler has a special sysroot distinct from what we
// actually downloaded, so we just always pass the `--sysroot` option.
cmd.arg("--sysroot").arg(&sysroot);
// actually downloaded, so we just always pass the `--sysroot` option,
// unless one is already set.
if !args.iter().any(|arg| arg == "--sysroot") {
cmd.arg("--sysroot").arg(&sysroot);
}

cmd.arg("-Zexternal-macro-backtrace");

Expand Down Expand Up @@ -285,20 +288,6 @@ fn main() {
}
}

// When running miri tests, we need to generate MIR for all libraries
if env::var("TEST_MIRI").ok().map_or(false, |val| val == "true") {
// The flags here should be kept in sync with `add_miri_default_args`
// in miri's `src/lib.rs`.
cmd.arg("-Zalways-encode-mir");
cmd.arg("--cfg=miri");
// These options are preferred by miri, to be able to perform better validation,
// but the bootstrap compiler might not understand them.
if stage != "0" {
cmd.arg("-Zmir-emit-retag");
cmd.arg("-Zmir-opt-level=0");
}
}

if let Ok(map) = env::var("RUSTC_DEBUGINFO_MAP") {
cmd.arg("--remap-path-prefix").arg(&map);
}
Expand Down
10 changes: 0 additions & 10 deletions src/bootstrap/builder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -543,15 +543,6 @@ impl<'a> Builder<'a> {
parent: Cell::new(None),
};

if kind == Kind::Dist {
assert!(
!builder.config.test_miri,
"Do not distribute with miri enabled.\n\
The distributed libraries would include all MIR (increasing binary size).
The distributed MIR would include validation statements."
);
}

builder
}

Expand Down Expand Up @@ -981,7 +972,6 @@ impl<'a> Builder<'a> {
PathBuf::from("/path/to/nowhere/rustdoc/not/required")
},
)
.env("TEST_MIRI", self.config.test_miri.to_string())
.env("RUSTC_ERROR_METADATA_DST", self.extended_error_dir());

if let Some(host_linker) = self.linker(compiler.host) {
Expand Down
4 changes: 0 additions & 4 deletions src/bootstrap/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,6 @@ pub struct Config {
pub low_priority: bool,
pub channel: String,
pub verbose_tests: bool,
pub test_miri: bool,
pub save_toolstates: Option<PathBuf>,
pub print_step_timings: bool,
pub missing_tools: bool,
Expand Down Expand Up @@ -315,7 +314,6 @@ struct Rust {
debug: Option<bool>,
dist_src: Option<bool>,
verbose_tests: Option<bool>,
test_miri: Option<bool>,
incremental: Option<bool>,
save_toolstates: Option<String>,
codegen_backends: Option<Vec<String>>,
Expand Down Expand Up @@ -375,7 +373,6 @@ impl Config {
config.codegen_tests = true;
config.ignore_git = false;
config.rust_dist_src = true;
config.test_miri = false;
config.rust_codegen_backends = vec![INTERNER.intern_str("llvm")];
config.rust_codegen_backends_dir = "codegen-backends".to_owned();
config.deny_warnings = true;
Expand Down Expand Up @@ -557,7 +554,6 @@ impl Config {
set(&mut config.channel, rust.channel.clone());
set(&mut config.rust_dist_src, rust.dist_src);
set(&mut config.verbose_tests, rust.verbose_tests);
set(&mut config.test_miri, rust.test_miri);
// in the case "false" is set explicitly, do not overwrite the command line args
if let Some(true) = rust.incremental {
config.incremental = true;
Expand Down
1 change: 0 additions & 1 deletion src/bootstrap/configure.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ def v(*args):
o("compiler-docs", "build.compiler-docs", "build compiler documentation")
o("optimize-tests", "rust.optimize-tests", "build tests with optimizations")
o("parallel-compiler", "rust.parallel-compiler", "build a multi-threaded rustc")
o("test-miri", "rust.test-miri", "run miri's test suite")
o("verbose-tests", "rust.verbose-tests", "enable verbose output when running tests")
o("ccache", "llvm.ccache", "invoke gcc/clang via ccache to reuse object files between builds")
o("sccache", None, "invoke gcc/clang via sccache to reuse object files between builds")
Expand Down
4 changes: 1 addition & 3 deletions src/bootstrap/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -540,9 +540,7 @@ impl Build {
Mode::Rustc => "-rustc",
Mode::Codegen => "-codegen",
Mode::ToolBootstrap => "-bootstrap-tools",
Mode::ToolStd => "-tools",
Mode::ToolTest => "-tools",
Mode::ToolRustc => "-tools",
Mode::ToolStd | Mode::ToolTest | Mode::ToolRustc => "-tools",
};
self.out.join(&*compiler.host)
.join(format!("stage{}{}", compiler.stage, suffix))
Expand Down
92 changes: 78 additions & 14 deletions src/bootstrap/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -363,11 +363,9 @@ pub struct Miri {
impl Step for Miri {
type Output = ();
const ONLY_HOSTS: bool = true;
const DEFAULT: bool = true;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
let test_miri = run.builder.config.test_miri;
run.path("src/tools/miri").default_condition(test_miri)
run.path("src/tools/miri")
}

fn make_run(run: RunConfig<'_>) {
Expand All @@ -389,26 +387,92 @@ impl Step for Miri {
extra_features: Vec::new(),
});
if let Some(miri) = miri {
let mut cargo = tool::prepare_tool_cargo(builder,
compiler,
Mode::ToolRustc,
host,
"test",
"src/tools/miri",
SourceType::Submodule,
&[]);
// # Run `cargo miri setup`.
// As a side-effect, this will install xargo.
let mut cargo = tool::prepare_tool_cargo(
builder,
compiler,
Mode::ToolRustc,
host,
"run",
"src/tools/miri",
SourceType::Submodule,
&[],
);
cargo
.arg("--bin")
.arg("cargo-miri")
.arg("--")
.arg("miri")
.arg("setup");

// Tell `cargo miri` not to worry about the sysroot mismatch (we built with
// stage1 but run with stage2).
cargo.env("MIRI_SKIP_SYSROOT_CHECK", "1");
// Tell `cargo miri setup` where to find the sources.
cargo.env("XARGO_RUST_SRC", builder.src.join("src"));
// Debug things.
cargo.env("RUST_BACKTRACE", "1");
// Configure `cargo install` path, and let cargo-miri know that that's where
// xargo ends up.
cargo.env("CARGO_INSTALL_ROOT", &builder.out); // cargo adds a `bin/`
cargo.env("XARGO", builder.out.join("bin").join("xargo"));

if !try_run(builder, &mut cargo) {
return;
}

// # Determine where Miri put its sysroot.
// To this end, we run `cargo miri setup --env` and capture the output.
// (We do this separately from the above so that when the setup actually
// happens we get some output.)
// We re-use the `cargo` from above.
cargo.arg("--env");

// FIXME: Is there a way in which we can re-use the usual `run` helpers?
let miri_sysroot = if builder.config.dry_run {
String::new()
} else {
builder.verbose(&format!("running: {:?}", cargo));
let out = cargo.output()
.expect("We already ran `cargo miri setup` before and that worked");
assert!(out.status.success(), "`cargo miri setup` returned with non-0 exit code");
// Output is "MIRI_SYSROOT=<str>\n".
let stdout = String::from_utf8(out.stdout)
.expect("`cargo miri setup` stdout is not valid UTF-8");
let stdout = stdout.trim();
builder.verbose(&format!("`cargo miri setup --env` returned: {:?}", stdout));
let sysroot = stdout.splitn(2, '=')
.nth(1).expect("`cargo miri setup` stdout did not contain '='");
sysroot.to_owned()
};

// # Run `cargo test`.
let mut cargo = tool::prepare_tool_cargo(
builder,
compiler,
Mode::ToolRustc,
host,
"test",
"src/tools/miri",
SourceType::Submodule,
&[],
);

// miri tests need to know about the stage sysroot
cargo.env("MIRI_SYSROOT", builder.sysroot(compiler));
cargo.env("MIRI_SYSROOT", miri_sysroot);
cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
cargo.env("MIRI_PATH", miri);

builder.add_rustc_lib_path(compiler, &mut cargo);

if try_run(builder, &mut cargo) {
builder.save_toolstate("miri", ToolState::TestPass);
if !try_run(builder, &mut cargo) {
return;
}

// # Done!
builder.save_toolstate("miri", ToolState::TestPass);
} else {
eprintln!("failed to test miri: could not build");
}
Expand Down
2 changes: 1 addition & 1 deletion src/ci/azure-pipelines/auto.yml
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,7 @@ jobs:
x86_64-msvc-tools:
MSYS_BITS: 64
SCRIPT: src/ci/docker/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstates.json windows
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json --enable-test-miri
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json

# 32/64-bit MinGW builds.
#
Expand Down
1 change: 0 additions & 1 deletion src/ci/docker/x86_64-gnu-tools/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,5 @@ COPY x86_64-gnu-tools/repo.sh /tmp/

ENV RUST_CONFIGURE_ARGS \
--build=x86_64-unknown-linux-gnu \
--enable-test-miri \
--save-toolstates=/tmp/toolstates.json
ENV SCRIPT /tmp/checktools.sh ../x.py /tmp/toolstates.json linux
2 changes: 1 addition & 1 deletion src/tools/miri

0 comments on commit fea43aa

Please sign in to comment.