Skip to content

Commit b7d2a81

Browse files
committed
Auto merge of rust-lang#126476 - ferrocene:pa-bootstrap-test-local-rustc, r=<try>
Fix running bootstrap tests with a local Rust toolchain as the stage0 When configuring a local Rust toolchain as the stage0 (with `build.rustc` and `build.cargo` in `config.toml`) we noticed there were test failures (both on the Python and the Rust side) due to bootstrap not being able to find rustc and Cargo. This was due to those two `config.toml` settings not being propagated in the tests. This PR fixes the issue by ensuring rustc and cargo are always configured in tests, using the parent bootstrap's `initial_rustc` and `initial_cargo`. try-job: x86_64-msvc Fixes rust-lang#105766
2 parents 59a4f02 + 198c809 commit b7d2a81

File tree

3 files changed

+51
-3
lines changed

3 files changed

+51
-3
lines changed

src/bootstrap/bootstrap_test.py

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -138,6 +138,25 @@ def build_args(self, configure_args=None, args=None, env=None):
138138
if env is None:
139139
env = {}
140140

141+
# This test ends up invoking build_bootstrap_cmd, which searches for
142+
# the Cargo binary and errors out if it cannot be found. This is not a
143+
# problem in most cases, but there is a scenario where it would cause
144+
# the test to fail.
145+
#
146+
# When a custom local Cargo is configured in config.toml (with the
147+
# build.cargo setting), no Cargo is downloaded to any location known by
148+
# bootstrap, and bootstrap relies on that setting to find it.
149+
#
150+
# In this test though we are not using the config.toml of the caller:
151+
# we are generating a blank one instead. If we don't set build.cargo in
152+
# it, the test will have no way to find Cargo, failing the test.
153+
cargo_bin = os.environ.get("BOOTSTRAP_TEST_CARGO_BIN")
154+
if cargo_bin is not None:
155+
configure_args += ["--set", "build.cargo=" + cargo_bin]
156+
rustc_bin = os.environ.get("BOOTSTRAP_TEST_RUSTC_BIN")
157+
if rustc_bin is not None:
158+
configure_args += ["--set", "build.rustc=" + rustc_bin]
159+
141160
env = env.copy()
142161
env["PATH"] = os.environ["PATH"]
143162

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2979,6 +2979,8 @@ impl Step for Bootstrap {
29792979
.args(["-m", "unittest", "bootstrap_test.py"])
29802980
.env("BUILD_DIR", &builder.out)
29812981
.env("BUILD_PLATFORM", builder.build.build.triple)
2982+
.env("BOOTSTRAP_TEST_RUSTC_BIN", &builder.initial_rustc)
2983+
.env("BOOTSTRAP_TEST_CARGO_BIN", &builder.initial_cargo)
29822984
.current_dir(builder.src.join("src/bootstrap/"));
29832985
// NOTE: we intentionally don't pass test_args here because the args for unittest and cargo test are mutually incompatible.
29842986
// Use `python -m unittest` manually if you want to pass arguments.

src/bootstrap/src/core/config/config.rs

Lines changed: 30 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1189,7 +1189,19 @@ impl Config {
11891189
pub fn parse(args: &[String]) -> Config {
11901190
#[cfg(test)]
11911191
fn get_toml(_: &Path) -> TomlConfig {
1192-
TomlConfig::default()
1192+
let mut default = TomlConfig::default();
1193+
1194+
// When configuring bootstrap for tests, make sure to set the rustc and Cargo to the
1195+
// same ones used to call the tests. If we don't do that, bootstrap will use its own
1196+
// detection logic to find a suitable rustc and Cargo, which doesn't work when the
1197+
// caller is specìfying a custom local rustc or Cargo in their config.toml.
1198+
default.build = Some(Build {
1199+
rustc: std::env::var_os("RUSTC").map(|v| v.into()),
1200+
cargo: std::env::var_os("CARGO").map(|v| v.into()),
1201+
..Build::default()
1202+
});
1203+
1204+
default
11931205
}
11941206

11951207
#[cfg(not(test))]
@@ -1441,14 +1453,24 @@ impl Config {
14411453
config.out = absolute(&config.out).expect("can't make empty path absolute");
14421454
}
14431455

1456+
// Hacky way to determine the executable suffix for the build target. We cannot use
1457+
// std::env::consts::EXE_SUFFIX as the build target might not be the target bootstrap was
1458+
// compiled with.
1459+
let initial_exe_suffix = if config.build.triple.contains("windows") { ".exe" } else { "" };
1460+
14441461
config.initial_rustc = if let Some(rustc) = rustc {
14451462
if !flags.skip_stage0_validation {
14461463
config.check_stage0_version(&rustc, "rustc");
14471464
}
14481465
rustc
14491466
} else {
14501467
config.download_beta_toolchain();
1451-
config.out.join(config.build.triple).join("stage0/bin/rustc")
1468+
config
1469+
.out
1470+
.join(config.build.triple)
1471+
.join("stage0")
1472+
.join("bin")
1473+
.join(format!("rustc{initial_exe_suffix}"))
14521474
};
14531475

14541476
config.initial_cargo = if let Some(cargo) = cargo {
@@ -1458,7 +1480,12 @@ impl Config {
14581480
cargo
14591481
} else {
14601482
config.download_beta_toolchain();
1461-
config.out.join(config.build.triple).join("stage0/bin/cargo")
1483+
config
1484+
.out
1485+
.join(config.build.triple)
1486+
.join("stage0")
1487+
.join("bin")
1488+
.join(format!("cargo{initial_exe_suffix}"))
14621489
};
14631490

14641491
// NOTE: it's important this comes *after* we set `initial_rustc` just above.

0 commit comments

Comments
 (0)