Skip to content

Commit 47da014

Browse files
committed
Make x test cargo stage N test rustc stage N
1 parent 1d1efed commit 47da014

File tree

2 files changed

+47
-13
lines changed

2 files changed

+47
-13
lines changed

src/bootstrap/src/core/build_steps/test.rs

Lines changed: 40 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44
//! However, this contains ~all test parts we expect people to be able to build and run locally.
55
66
use std::collections::HashSet;
7+
use std::env::join_paths;
78
use std::ffi::{OsStr, OsString};
89
use std::path::{Path, PathBuf};
910
use std::{env, fs, iter};
1011

12+
use build_helper::exit;
1113
#[cfg(feature = "tracing")]
1214
use tracing::instrument;
1315

@@ -242,8 +244,12 @@ impl Step for Cargotest {
242244
}
243245

244246
fn make_run(run: RunConfig<'_>) {
245-
// FIXME: support testing stage 0 cargo?
246-
assert!(run.builder.top_stage > 0);
247+
if run.builder.top_stage == 0 {
248+
eprintln!(
249+
"ERROR: running cargotest with stage 0 is currently unsupported. Use at least stage 1."
250+
);
251+
exit!(1);
252+
}
247253
run.builder.ensure(Cargotest {
248254
build_compiler: run.builder.compiler(run.builder.top_stage - 1, run.target),
249255
host: run.target,
@@ -322,14 +328,18 @@ impl Step for Cargo {
322328

323329
/// Runs `cargo test` for `cargo` packaged with Rust.
324330
fn run(self, builder: &Builder<'_>) {
325-
// FIXME: we now use the same compiler to build cargo and then we also test that compiler
326-
// using cargo.
327-
// We could build cargo using a different compiler, but that complicates some things,
328-
// because when we run cargo tests, the crates that are being compiled are accessing the
329-
// sysroot of the build compiler, rather than the compiler being tested.
330-
// Since these two compilers are currently the same, it works.
331+
// When we do a "stage 1 cargo test", it means that we test the stage 1 rustc
332+
// using stage 1 cargo. So we actually build cargo using the stage 0 compiler, and then
333+
// run its tests against the stage 1 compiler (called `tested_compiler` below).
331334
builder.ensure(tool::Cargo::from_build_compiler(self.build_compiler, self.host));
332335

336+
let tested_compiler = builder.compiler(self.build_compiler.stage + 1, self.host);
337+
builder.std(tested_compiler, self.host);
338+
// We also need to build rustdoc for cargo tests
339+
// It will be located in the bindir of `tested_compiler`, so we don't need to explicitly
340+
// pass its path to Cargo.
341+
builder.rustdoc_for_compiler(tested_compiler);
342+
333343
let cargo = tool::prepare_tool_cargo(
334344
builder,
335345
self.build_compiler,
@@ -350,7 +360,27 @@ impl Step for Cargo {
350360
// Forcibly disable tests using nightly features since any changes to
351361
// those features won't be able to land.
352362
cargo.env("CARGO_TEST_DISABLE_NIGHTLY", "1");
353-
cargo.env("PATH", path_for_cargo(builder, self.build_compiler));
363+
364+
// Configure PATH to find the right rustc. NB. we have to use PATH
365+
// and not RUSTC because the Cargo test suite has tests that will
366+
// fail if rustc is not spelled `rustc`.
367+
cargo.env("PATH", bin_path_for_cargo(builder, tested_compiler));
368+
369+
// The `cargo` command configured above has dylib dir path set to the `build_compiler`'s
370+
// libdir. That causes issues in cargo test, because the programs that cargo compiles are
371+
// incorrectly picking that libdir, even though they should be picking the
372+
// `tested_compiler`'s libdir. We thus have to override the precedence here.
373+
let existing_dylib_path = cargo
374+
.get_envs()
375+
.find(|(k, _)| *k == OsStr::new(dylib_path_var()))
376+
.and_then(|(_, v)| v)
377+
.unwrap_or(OsStr::new(""));
378+
cargo.env(
379+
dylib_path_var(),
380+
join_paths([builder.rustc_libdir(tested_compiler).as_ref(), existing_dylib_path])
381+
.unwrap_or_default(),
382+
);
383+
354384
// Cargo's test suite uses `CARGO_RUSTC_CURRENT_DIR` to determine the path that `file!` is
355385
// relative to. Cargo no longer sets this env var, so we have to do that. This has to be the
356386
// same value as `-Zroot-dir`.
@@ -859,10 +889,7 @@ impl Step for Clippy {
859889
}
860890
}
861891

862-
fn path_for_cargo(builder: &Builder<'_>, compiler: Compiler) -> OsString {
863-
// Configure PATH to find the right rustc. NB. we have to use PATH
864-
// and not RUSTC because the Cargo test suite has tests that will
865-
// fail if rustc is not spelled `rustc`.
892+
fn bin_path_for_cargo(builder: &Builder<'_>, compiler: Compiler) -> OsString {
866893
let path = builder.sysroot(compiler).join("bin");
867894
let old_path = env::var_os("PATH").unwrap_or_default();
868895
env::join_paths(iter::once(path).chain(env::split_paths(&old_path))).expect("")

src/bootstrap/src/core/builder/tests.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,6 +1607,10 @@ mod snapshot {
16071607
.path("cargo")
16081608
.render_steps(), @r"
16091609
[build] rustc 0 <host> -> cargo 1 <host>
1610+
[build] llvm <host>
1611+
[build] rustc 0 <host> -> rustc 1 <host>
1612+
[build] rustc 1 <host> -> std 1 <host>
1613+
[build] rustdoc 1 <host>
16101614
[build] rustdoc 0 <host>
16111615
");
16121616
}
@@ -1623,6 +1627,9 @@ mod snapshot {
16231627
[build] rustc 0 <host> -> rustc 1 <host>
16241628
[build] rustc 1 <host> -> std 1 <host>
16251629
[build] rustc 1 <host> -> cargo 2 <host>
1630+
[build] rustc 1 <host> -> rustc 2 <host>
1631+
[build] rustc 2 <host> -> std 2 <host>
1632+
[build] rustdoc 2 <host>
16261633
[build] rustdoc 1 <host>
16271634
");
16281635
}

0 commit comments

Comments
 (0)