Skip to content

Commit 6fc6753

Browse files
committed
Make build compiler explicit in check::Rustc and check::Std
1 parent 948eb5e commit 6fc6753

File tree

2 files changed

+56
-32
lines changed

2 files changed

+56
-32
lines changed

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

Lines changed: 54 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
//! Implementation of compiling the compiler and standard library, in "check"-based modes.
22
3+
use build_helper::exit;
4+
35
use crate::core::build_steps::compile::{
46
add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo, std_crates_for_run_make,
57
};
@@ -9,10 +11,12 @@ use crate::core::builder::{
911
};
1012
use crate::core::config::TargetSelection;
1113
use crate::utils::build_stamp::{self, BuildStamp};
12-
use crate::{Mode, Subcommand};
14+
use crate::{Compiler, Mode, Subcommand};
1315

1416
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1517
pub struct Std {
18+
/// Compiler that will check this std.
19+
pub build_compiler: Compiler,
1620
pub target: TargetSelection,
1721
/// Whether to build only a subset of crates.
1822
///
@@ -25,8 +29,8 @@ pub struct Std {
2529
impl Std {
2630
const CRATE_OR_DEPS: &[&str] = &["sysroot", "coretests", "alloctests"];
2731

28-
pub fn new(target: TargetSelection) -> Self {
29-
Self { target, crates: vec![] }
32+
pub fn new(build_compiler: Compiler, target: TargetSelection) -> Self {
33+
Self { build_compiler, target, crates: vec![] }
3034
}
3135
}
3236

@@ -45,7 +49,11 @@ impl Step for Std {
4549

4650
fn make_run(run: RunConfig<'_>) {
4751
let crates = std_crates_for_run_make(&run);
48-
run.builder.ensure(Std { target: run.target, crates });
52+
run.builder.ensure(Std {
53+
build_compiler: run.builder.compiler(run.builder.top_stage, run.target),
54+
target: run.target,
55+
crates,
56+
});
4957
}
5058

5159
fn run(self, builder: &Builder<'_>) {
@@ -58,9 +66,9 @@ impl Step for Std {
5866

5967
builder.require_submodule("library/stdarch", None);
6068

61-
let stage = builder.top_stage;
69+
let build_compiler = self.build_compiler;
70+
let stage = build_compiler.stage;
6271
let target = self.target;
63-
let build_compiler = builder.compiler(stage, builder.config.host_target);
6472

6573
let mut cargo = builder::Cargo::new(
6674
builder,
@@ -71,7 +79,7 @@ impl Step for Std {
7179
Kind::Check,
7280
);
7381

74-
std_cargo(builder, target, build_compiler.stage, &mut cargo);
82+
std_cargo(builder, target, stage, &mut cargo);
7583
if matches!(builder.config.cmd, Subcommand::Fix) {
7684
// By default, cargo tries to fix all targets. Tell it not to fix tests until we've added `test` to the sysroot.
7785
cargo.arg("--lib");
@@ -132,8 +140,17 @@ impl Step for Std {
132140
}
133141
}
134142

143+
fn default_compiler_for_checking_rustc(builder: &Builder<'_>) -> Compiler {
144+
// When checking the stage N compiler, we want to do it with the stage N-1 compiler,
145+
builder.compiler(builder.top_stage - 1, builder.config.host_target)
146+
}
147+
148+
/// Checks rustc using `build_compiler` and copies the built
149+
/// .rmeta files into the sysroot of `build_copoiler`.
135150
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
136151
pub struct Rustc {
152+
/// Compiler that will check this rustc.
153+
pub build_compiler: Compiler,
137154
pub target: TargetSelection,
138155
/// Whether to build only a subset of crates.
139156
///
@@ -144,13 +161,13 @@ pub struct Rustc {
144161
}
145162

146163
impl Rustc {
147-
pub fn new(target: TargetSelection, builder: &Builder<'_>) -> Self {
164+
pub fn new(builder: &Builder<'_>, build_compiler: Compiler, target: TargetSelection) -> Self {
148165
let crates = builder
149166
.in_tree_crates("rustc-main", Some(target))
150167
.into_iter()
151168
.map(|krate| krate.name.to_string())
152169
.collect();
153-
Self { target, crates }
170+
Self { build_compiler, target, crates }
154171
}
155172
}
156173

@@ -165,40 +182,46 @@ impl Step for Rustc {
165182

166183
fn make_run(run: RunConfig<'_>) {
167184
let crates = run.make_run_crates(Alias::Compiler);
168-
run.builder.ensure(Rustc { target: run.target, crates });
185+
run.builder.ensure(Rustc {
186+
target: run.target,
187+
build_compiler: default_compiler_for_checking_rustc(run.builder),
188+
crates,
189+
});
169190
}
170191

171-
/// Builds the compiler.
192+
/// Check the compiler.
172193
///
173-
/// This will build the compiler for a particular stage of the build using
194+
/// This will check the compiler for a particular stage of the build using
174195
/// the `compiler` targeting the `target` architecture. The artifacts
175196
/// created will also be linked into the sysroot directory.
176197
fn run(self, builder: &Builder<'_>) {
177-
let compiler = builder.compiler(builder.top_stage, builder.config.host_target);
198+
if builder.top_stage < 2 && builder.config.host_target != self.target {
199+
eprintln!("Cannot do a cross-compilation check on stage 1, use stage 2");
200+
exit!(1);
201+
}
202+
203+
let build_compiler = self.build_compiler;
178204
let target = self.target;
179205

180-
if compiler.stage != 0 {
181-
// If we're not in stage 0, then we won't have a std from the beta
182-
// compiler around. That means we need to make sure there's one in
183-
// the sysroot for the compiler to find. Otherwise, we're going to
184-
// fail when building crates that need to generate code (e.g., build
185-
// scripts and their dependencies).
186-
builder.std(compiler, compiler.host);
187-
builder.std(compiler, target);
188-
} else {
189-
builder.ensure(Std::new(target));
190-
}
206+
// Build host std for compiling build scripts
207+
builder.std(build_compiler, build_compiler.host);
208+
209+
// Build target std so that the checked rustc can link to it during the check
210+
// FIXME: maybe we can a way to only do a check of std here?
211+
// But for that we would have to copy the stdlib rmetas to the sysroot of the build
212+
// compiler, which conflicts with std rlibs, if we also build std.
213+
builder.std(build_compiler, target);
191214

192215
let mut cargo = builder::Cargo::new(
193216
builder,
194-
compiler,
217+
build_compiler,
195218
Mode::Rustc,
196219
SourceType::InTree,
197220
target,
198221
Kind::Check,
199222
);
200223

201-
rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates);
224+
rustc_cargo(builder, &mut cargo, target, &build_compiler, &self.crates);
202225

203226
// Explicitly pass -p for all compiler crates -- this will force cargo
204227
// to also check the tests/benches/examples for these crates, rather
@@ -213,12 +236,13 @@ impl Step for Rustc {
213236
None,
214237
);
215238

216-
let stamp = build_stamp::librustc_stamp(builder, compiler, target).with_prefix("check");
239+
let stamp =
240+
build_stamp::librustc_stamp(builder, build_compiler, target).with_prefix("check");
217241

218242
run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
219243

220-
let libdir = builder.sysroot_target_libdir(compiler, target);
221-
let hostdir = builder.sysroot_target_libdir(compiler, compiler.host);
244+
let libdir = builder.sysroot_target_libdir(build_compiler, target);
245+
let hostdir = builder.sysroot_target_libdir(build_compiler, build_compiler.host);
222246
add_to_sysroot(builder, &libdir, &hostdir, &stamp);
223247
}
224248

@@ -456,7 +480,7 @@ fn run_tool_check_step(
456480
let display_name = path.rsplit('/').next().unwrap();
457481
let compiler = builder.compiler(builder.top_stage, builder.config.host_target);
458482

459-
builder.ensure(Rustc::new(target, builder));
483+
builder.ensure(Rustc::new(builder, compiler, target));
460484

461485
let mut cargo = prepare_tool_cargo(
462486
builder,

src/bootstrap/src/core/build_steps/clippy.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -217,7 +217,7 @@ impl Step for Rustc {
217217
builder.std(compiler, compiler.host);
218218
builder.std(compiler, target);
219219
} else {
220-
builder.ensure(check::Std::new(target));
220+
builder.ensure(check::Std::new(compiler, target));
221221
}
222222
}
223223

@@ -289,7 +289,7 @@ macro_rules! lint_any {
289289
let target = self.target;
290290

291291
if !builder.download_rustc() {
292-
builder.ensure(check::Rustc::new(target, builder));
292+
builder.ensure(check::Rustc::new(builder, compiler, target));
293293
};
294294

295295
let cargo = prepare_tool_cargo(

0 commit comments

Comments
 (0)