Skip to content

Commit 2a4a411

Browse files
Rollup merge of #144011 - Zalathar:check-compiler-no-llvm, r=Kobzol
bootstrap: Don't trigger an unnecessary LLVM build from check builds Coming back to r-l/r development after a few weeks away, I found a major regression in my dev workflows: running `x check compiler` (either manually or via rust-analyzer) would have the side-effect of building LLVM, even though that shouldn't be necessary. For my main build directory this would be a minor annoyance, but for my separate rust-analyzer build directory it's a huge problem because it causes a completely separate build of LLVM, which takes a long time and should be completely unnecessary. --- After some investigation, I tracked down the problem to the `can_skip_build` check in this code: https://github.com/rust-lang/rust/blob/3014e79f9c8d5510ea7b3a3b70d171d0948b1e96/src/bootstrap/src/core/build_steps/compile.rs#L1382-L1396 Historically, this would skip the LLVM build for stage 0 check builds. But after the recent stage 0 std redesign and some associated check stage renumbering (e.g. #143048), the condition `builder.top_stage == build_stage` is now false, because `top_stage` is 1 (due to the renumbering) but `build_stage` is 0 (because a “stage 1” non-library check build still uses the stage 0 compiler). --- Because this is a critical contributor roadblock for me, I have tried to fix this in a relatively narrow way. It's possible that all of this surrounding logic could be greatly simplified (especially in light of the stage redesign changes), but I didn't want this fix to be held back by scope creep. --- (Zulip thread: https://rust-lang.zulipchat.com/#narrow/channel/326414-t-infra.2Fbootstrap/topic/Bootstrap.20incorrectly.20building.20LLVM.20for.20check.20builds/near/528991035)
2 parents 2461d6c + a028ca5 commit 2a4a411

File tree

4 files changed

+32
-28
lines changed

4 files changed

+32
-28
lines changed

src/bootstrap/src/core/build_steps/check.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -355,7 +355,7 @@ impl Step for CodegenBackend {
355355
cargo
356356
.arg("--manifest-path")
357357
.arg(builder.src.join(format!("compiler/rustc_codegen_{backend}/Cargo.toml")));
358-
rustc_cargo_env(builder, &mut cargo, target, build_compiler.stage);
358+
rustc_cargo_env(builder, &mut cargo, target);
359359

360360
let _guard = builder.msg_check(format!("rustc_codegen_{backend}"), target, None);
361361

src/bootstrap/src/core/build_steps/compile.rs

Lines changed: 21 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1316,15 +1316,10 @@ pub fn rustc_cargo(
13161316
cargo.env("RUSTC_WRAPPER", ccache);
13171317
}
13181318

1319-
rustc_cargo_env(builder, cargo, target, build_compiler.stage);
1319+
rustc_cargo_env(builder, cargo, target);
13201320
}
13211321

1322-
pub fn rustc_cargo_env(
1323-
builder: &Builder<'_>,
1324-
cargo: &mut Cargo,
1325-
target: TargetSelection,
1326-
build_stage: u32,
1327-
) {
1322+
pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) {
13281323
// Set some configuration variables picked up by build scripts and
13291324
// the compiler alike
13301325
cargo
@@ -1379,18 +1374,24 @@ pub fn rustc_cargo_env(
13791374
cargo.rustflag("--cfg=llvm_enzyme");
13801375
}
13811376

1382-
// Note that this is disabled if LLVM itself is disabled or we're in a check
1383-
// build. If we are in a check build we still go ahead here presuming we've
1384-
// detected that LLVM is already built and good to go which helps prevent
1385-
// busting caches (e.g. like #71152).
1377+
// These conditionals represent a tension between three forces:
1378+
// - For non-check builds, we need to define some LLVM-related environment
1379+
// variables, requiring LLVM to have been built.
1380+
// - For check builds, we want to avoid building LLVM if possible.
1381+
// - Check builds and non-check builds should have the same environment if
1382+
// possible, to avoid unnecessary rebuilds due to cache-busting.
1383+
//
1384+
// Therefore we try to avoid building LLVM for check builds, but only if
1385+
// building LLVM would be expensive. If "building" LLVM is cheap
1386+
// (i.e. it's already built or is downloadable), we prefer to maintain a
1387+
// consistent environment between check and non-check builds.
13861388
if builder.config.llvm_enabled(target) {
1387-
let building_is_expensive =
1389+
let building_llvm_is_expensive =
13881390
crate::core::build_steps::llvm::prebuilt_llvm_config(builder, target, false)
13891391
.should_build();
1390-
// `top_stage == stage` might be false for `check --stage 1`, if we are building the stage 1 compiler
1391-
let can_skip_build = builder.kind == Kind::Check && builder.top_stage == build_stage;
1392-
let should_skip_build = building_is_expensive && can_skip_build;
1393-
if !should_skip_build {
1392+
1393+
let skip_llvm = (builder.kind == Kind::Check) && building_llvm_is_expensive;
1394+
if !skip_llvm {
13941395
rustc_llvm_env(builder, cargo, target)
13951396
}
13961397
}
@@ -1407,6 +1408,9 @@ pub fn rustc_cargo_env(
14071408

14081409
/// Pass down configuration from the LLVM build into the build of
14091410
/// rustc_llvm and rustc_codegen_llvm.
1411+
///
1412+
/// Note that this has the side-effect of _building LLVM_, which is sometimes
1413+
/// unwanted (e.g. for check builds).
14101414
fn rustc_llvm_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetSelection) {
14111415
if builder.config.is_rust_llvm(target) {
14121416
cargo.env("LLVM_RUSTLLVM", "1");
@@ -1665,7 +1669,7 @@ impl Step for CodegenBackend {
16651669
cargo
16661670
.arg("--manifest-path")
16671671
.arg(builder.src.join(format!("compiler/rustc_codegen_{backend}/Cargo.toml")));
1668-
rustc_cargo_env(builder, &mut cargo, target, compiler.stage);
1672+
rustc_cargo_env(builder, &mut cargo, target);
16691673

16701674
// Ideally, we'd have a separate step for the individual codegen backends,
16711675
// like we have in tests (test::CodegenGCC) but that would require a lot of restructuring.

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3387,7 +3387,7 @@ impl Step for CodegenCranelift {
33873387
cargo
33883388
.arg("--manifest-path")
33893389
.arg(builder.src.join("compiler/rustc_codegen_cranelift/build_system/Cargo.toml"));
3390-
compile::rustc_cargo_env(builder, &mut cargo, target, compiler.stage);
3390+
compile::rustc_cargo_env(builder, &mut cargo, target);
33913391

33923392
// Avoid incremental cache issues when changing rustc
33933393
cargo.env("CARGO_BUILD_INCREMENTAL", "false");
@@ -3519,7 +3519,7 @@ impl Step for CodegenGCC {
35193519
cargo
35203520
.arg("--manifest-path")
35213521
.arg(builder.src.join("compiler/rustc_codegen_gcc/build_system/Cargo.toml"));
3522-
compile::rustc_cargo_env(builder, &mut cargo, target, compiler.stage);
3522+
compile::rustc_cargo_env(builder, &mut cargo, target);
35233523
add_cg_gcc_cargo_flags(&mut cargo, &gcc);
35243524

35253525
// Avoid incremental cache issues when changing rustc

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

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,11 @@ mod snapshot {
712712
[build] llvm <host>
713713
[build] rustc 0 <host> -> rustc 1 <host>
714714
");
715+
}
715716

717+
#[test]
718+
fn build_rustc_no_explicit_stage() {
719+
let ctx = TestCtx::new();
716720
insta::assert_snapshot!(
717721
ctx.config("build")
718722
.path("rustc")
@@ -1303,17 +1307,19 @@ mod snapshot {
13031307
ctx.config("check")
13041308
.path("compiler")
13051309
.render_steps(), @r"
1306-
[build] llvm <host>
13071310
[check] rustc 0 <host> -> rustc 1 <host>
13081311
[check] rustc 0 <host> -> cranelift 1 <host>
13091312
[check] rustc 0 <host> -> gcc 1 <host>
13101313
");
1314+
}
13111315

1316+
#[test]
1317+
fn check_rustc_no_explicit_stage() {
1318+
let ctx = TestCtx::new();
13121319
insta::assert_snapshot!(
13131320
ctx.config("check")
13141321
.path("rustc")
13151322
.render_steps(), @r"
1316-
[build] llvm <host>
13171323
[check] rustc 0 <host> -> rustc 1 <host>
13181324
");
13191325
}
@@ -1333,7 +1339,6 @@ mod snapshot {
13331339
.path("compiler")
13341340
.stage(1)
13351341
.render_steps(), @r"
1336-
[build] llvm <host>
13371342
[check] rustc 0 <host> -> rustc 1 <host>
13381343
[check] rustc 0 <host> -> cranelift 1 <host>
13391344
[check] rustc 0 <host> -> gcc 1 <host>
@@ -1465,7 +1470,6 @@ mod snapshot {
14651470
.paths(&["library", "compiler"])
14661471
.args(&args)
14671472
.render_steps(), @r"
1468-
[build] llvm <host>
14691473
[check] rustc 0 <host> -> rustc 1 <host>
14701474
[check] rustc 0 <host> -> cranelift 1 <host>
14711475
[check] rustc 0 <host> -> gcc 1 <host>
@@ -1479,7 +1483,6 @@ mod snapshot {
14791483
ctx.config("check")
14801484
.path("miri")
14811485
.render_steps(), @r"
1482-
[build] llvm <host>
14831486
[check] rustc 0 <host> -> rustc 1 <host>
14841487
[check] rustc 0 <host> -> Miri 1 <host>
14851488
");
@@ -1500,7 +1503,6 @@ mod snapshot {
15001503
.path("miri")
15011504
.stage(1)
15021505
.render_steps(), @r"
1503-
[build] llvm <host>
15041506
[check] rustc 0 <host> -> rustc 1 <host>
15051507
[check] rustc 0 <host> -> Miri 1 <host>
15061508
");
@@ -1553,7 +1555,6 @@ mod snapshot {
15531555
ctx.config("check")
15541556
.path("rustc_codegen_cranelift")
15551557
.render_steps(), @r"
1556-
[build] llvm <host>
15571558
[check] rustc 0 <host> -> rustc 1 <host>
15581559
[check] rustc 0 <host> -> cranelift 1 <host>
15591560
[check] rustc 0 <host> -> gcc 1 <host>
@@ -1567,7 +1568,6 @@ mod snapshot {
15671568
ctx.config("check")
15681569
.path("rust-analyzer")
15691570
.render_steps(), @r"
1570-
[build] llvm <host>
15711571
[check] rustc 0 <host> -> rustc 1 <host>
15721572
[check] rustc 0 <host> -> rust-analyzer 1 <host>
15731573
");

0 commit comments

Comments
 (0)