Skip to content

Commit 8abf29f

Browse files
authored
Rollup merge of rust-lang#63162 - RalfJung:miri-xargo, r=alexcrichton
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
2 parents 2d1a551 + e6be1d7 commit 8abf29f

File tree

10 files changed

+86
-55
lines changed

10 files changed

+86
-55
lines changed

config.toml.example

-4
Original file line numberDiff line numberDiff line change
@@ -368,10 +368,6 @@
368368
# When creating source tarballs whether or not to create a source tarball.
369369
#dist-src = false
370370

371-
# Whether to also run the Miri tests suite when running tests.
372-
# As a side-effect also generates MIR for all libraries.
373-
#test-miri = false
374-
375371
# After building or testing extended tools (e.g. clippy and rustfmt), append the
376372
# result (broken, compiling, testing) into this JSON file.
377373
#save-toolstates = "/path/to/toolstates.json"

src/bootstrap/bin/rustc.rs

+5-16
Original file line numberDiff line numberDiff line change
@@ -143,8 +143,11 @@ fn main() {
143143

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

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

@@ -285,20 +288,6 @@ fn main() {
285288
}
286289
}
287290

288-
// When running miri tests, we need to generate MIR for all libraries
289-
if env::var("TEST_MIRI").ok().map_or(false, |val| val == "true") {
290-
// The flags here should be kept in sync with `add_miri_default_args`
291-
// in miri's `src/lib.rs`.
292-
cmd.arg("-Zalways-encode-mir");
293-
cmd.arg("--cfg=miri");
294-
// These options are preferred by miri, to be able to perform better validation,
295-
// but the bootstrap compiler might not understand them.
296-
if stage != "0" {
297-
cmd.arg("-Zmir-emit-retag");
298-
cmd.arg("-Zmir-opt-level=0");
299-
}
300-
}
301-
302291
if let Ok(map) = env::var("RUSTC_DEBUGINFO_MAP") {
303292
cmd.arg("--remap-path-prefix").arg(&map);
304293
}

src/bootstrap/builder.rs

-10
Original file line numberDiff line numberDiff line change
@@ -543,15 +543,6 @@ impl<'a> Builder<'a> {
543543
parent: Cell::new(None),
544544
};
545545

546-
if kind == Kind::Dist {
547-
assert!(
548-
!builder.config.test_miri,
549-
"Do not distribute with miri enabled.\n\
550-
The distributed libraries would include all MIR (increasing binary size).
551-
The distributed MIR would include validation statements."
552-
);
553-
}
554-
555546
builder
556547
}
557548

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

987977
if let Some(host_linker) = self.linker(compiler.host) {

src/bootstrap/config.rs

-4
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,6 @@ pub struct Config {
128128
pub low_priority: bool,
129129
pub channel: String,
130130
pub verbose_tests: bool,
131-
pub test_miri: bool,
132131
pub save_toolstates: Option<PathBuf>,
133132
pub print_step_timings: bool,
134133
pub missing_tools: bool,
@@ -315,7 +314,6 @@ struct Rust {
315314
debug: Option<bool>,
316315
dist_src: Option<bool>,
317316
verbose_tests: Option<bool>,
318-
test_miri: Option<bool>,
319317
incremental: Option<bool>,
320318
save_toolstates: Option<String>,
321319
codegen_backends: Option<Vec<String>>,
@@ -375,7 +373,6 @@ impl Config {
375373
config.codegen_tests = true;
376374
config.ignore_git = false;
377375
config.rust_dist_src = true;
378-
config.test_miri = false;
379376
config.rust_codegen_backends = vec![INTERNER.intern_str("llvm")];
380377
config.rust_codegen_backends_dir = "codegen-backends".to_owned();
381378
config.deny_warnings = true;
@@ -557,7 +554,6 @@ impl Config {
557554
set(&mut config.channel, rust.channel.clone());
558555
set(&mut config.rust_dist_src, rust.dist_src);
559556
set(&mut config.verbose_tests, rust.verbose_tests);
560-
set(&mut config.test_miri, rust.test_miri);
561557
// in the case "false" is set explicitly, do not overwrite the command line args
562558
if let Some(true) = rust.incremental {
563559
config.incremental = true;

src/bootstrap/configure.py

-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,6 @@ def v(*args):
3636
o("compiler-docs", "build.compiler-docs", "build compiler documentation")
3737
o("optimize-tests", "rust.optimize-tests", "build tests with optimizations")
3838
o("parallel-compiler", "rust.parallel-compiler", "build a multi-threaded rustc")
39-
o("test-miri", "rust.test-miri", "run miri's test suite")
4039
o("verbose-tests", "rust.verbose-tests", "enable verbose output when running tests")
4140
o("ccache", "llvm.ccache", "invoke gcc/clang via ccache to reuse object files between builds")
4241
o("sccache", None, "invoke gcc/clang via sccache to reuse object files between builds")

src/bootstrap/lib.rs

+1-3
Original file line numberDiff line numberDiff line change
@@ -540,9 +540,7 @@ impl Build {
540540
Mode::Rustc => "-rustc",
541541
Mode::Codegen => "-codegen",
542542
Mode::ToolBootstrap => "-bootstrap-tools",
543-
Mode::ToolStd => "-tools",
544-
Mode::ToolTest => "-tools",
545-
Mode::ToolRustc => "-tools",
543+
Mode::ToolStd | Mode::ToolTest | Mode::ToolRustc => "-tools",
546544
};
547545
self.out.join(&*compiler.host)
548546
.join(format!("stage{}{}", compiler.stage, suffix))

src/bootstrap/test.rs

+78-14
Original file line numberDiff line numberDiff line change
@@ -363,11 +363,9 @@ pub struct Miri {
363363
impl Step for Miri {
364364
type Output = ();
365365
const ONLY_HOSTS: bool = true;
366-
const DEFAULT: bool = true;
367366

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

373371
fn make_run(run: RunConfig<'_>) {
@@ -389,26 +387,92 @@ impl Step for Miri {
389387
extra_features: Vec::new(),
390388
});
391389
if let Some(miri) = miri {
392-
let mut cargo = tool::prepare_tool_cargo(builder,
393-
compiler,
394-
Mode::ToolRustc,
395-
host,
396-
"test",
397-
"src/tools/miri",
398-
SourceType::Submodule,
399-
&[]);
390+
// # Run `cargo miri setup`.
391+
// As a side-effect, this will install xargo.
392+
let mut cargo = tool::prepare_tool_cargo(
393+
builder,
394+
compiler,
395+
Mode::ToolRustc,
396+
host,
397+
"run",
398+
"src/tools/miri",
399+
SourceType::Submodule,
400+
&[],
401+
);
402+
cargo
403+
.arg("--bin")
404+
.arg("cargo-miri")
405+
.arg("--")
406+
.arg("miri")
407+
.arg("setup");
408+
409+
// Tell `cargo miri` not to worry about the sysroot mismatch (we built with
410+
// stage1 but run with stage2).
411+
cargo.env("MIRI_SKIP_SYSROOT_CHECK", "1");
412+
// Tell `cargo miri setup` where to find the sources.
413+
cargo.env("XARGO_RUST_SRC", builder.src.join("src"));
414+
// Debug things.
415+
cargo.env("RUST_BACKTRACE", "1");
416+
// Configure `cargo install` path, and let cargo-miri know that that's where
417+
// xargo ends up.
418+
cargo.env("CARGO_INSTALL_ROOT", &builder.out); // cargo adds a `bin/`
419+
cargo.env("XARGO", builder.out.join("bin").join("xargo"));
420+
421+
if !try_run(builder, &mut cargo) {
422+
return;
423+
}
424+
425+
// # Determine where Miri put its sysroot.
426+
// To this end, we run `cargo miri setup --env` and capture the output.
427+
// (We do this separately from the above so that when the setup actually
428+
// happens we get some output.)
429+
// We re-use the `cargo` from above.
430+
cargo.arg("--env");
431+
432+
// FIXME: Is there a way in which we can re-use the usual `run` helpers?
433+
let miri_sysroot = if builder.config.dry_run {
434+
String::new()
435+
} else {
436+
builder.verbose(&format!("running: {:?}", cargo));
437+
let out = cargo.output()
438+
.expect("We already ran `cargo miri setup` before and that worked");
439+
assert!(out.status.success(), "`cargo miri setup` returned with non-0 exit code");
440+
// Output is "MIRI_SYSROOT=<str>\n".
441+
let stdout = String::from_utf8(out.stdout)
442+
.expect("`cargo miri setup` stdout is not valid UTF-8");
443+
let stdout = stdout.trim();
444+
builder.verbose(&format!("`cargo miri setup --env` returned: {:?}", stdout));
445+
let sysroot = stdout.splitn(2, '=')
446+
.nth(1).expect("`cargo miri setup` stdout did not contain '='");
447+
sysroot.to_owned()
448+
};
449+
450+
// # Run `cargo test`.
451+
let mut cargo = tool::prepare_tool_cargo(
452+
builder,
453+
compiler,
454+
Mode::ToolRustc,
455+
host,
456+
"test",
457+
"src/tools/miri",
458+
SourceType::Submodule,
459+
&[],
460+
);
400461

401462
// miri tests need to know about the stage sysroot
402-
cargo.env("MIRI_SYSROOT", builder.sysroot(compiler));
463+
cargo.env("MIRI_SYSROOT", miri_sysroot);
403464
cargo.env("RUSTC_TEST_SUITE", builder.rustc(compiler));
404465
cargo.env("RUSTC_LIB_PATH", builder.rustc_libdir(compiler));
405466
cargo.env("MIRI_PATH", miri);
406467

407468
builder.add_rustc_lib_path(compiler, &mut cargo);
408469

409-
if try_run(builder, &mut cargo) {
410-
builder.save_toolstate("miri", ToolState::TestPass);
470+
if !try_run(builder, &mut cargo) {
471+
return;
411472
}
473+
474+
// # Done!
475+
builder.save_toolstate("miri", ToolState::TestPass);
412476
} else {
413477
eprintln!("failed to test miri: could not build");
414478
}

src/ci/azure-pipelines/auto.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -254,7 +254,7 @@ jobs:
254254
x86_64-msvc-tools:
255255
MSYS_BITS: 64
256256
SCRIPT: src/ci/docker/x86_64-gnu-tools/checktools.sh x.py /tmp/toolstates.json windows
257-
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json --enable-test-miri
257+
RUST_CONFIGURE_ARGS: --build=x86_64-pc-windows-msvc --save-toolstates=/tmp/toolstates.json
258258

259259
# 32/64-bit MinGW builds.
260260
#

src/ci/docker/x86_64-gnu-tools/Dockerfile

-1
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,5 @@ COPY x86_64-gnu-tools/repo.sh /tmp/
2323

2424
ENV RUST_CONFIGURE_ARGS \
2525
--build=x86_64-unknown-linux-gnu \
26-
--enable-test-miri \
2726
--save-toolstates=/tmp/toolstates.json
2827
ENV SCRIPT /tmp/checktools.sh ../x.py /tmp/toolstates.json linux

0 commit comments

Comments
 (0)