Skip to content

Commit 1c8801e

Browse files
committed
Use the bootstrap compiler for x check on bootstrap tools
1 parent 10a76d6 commit 1c8801e

File tree

2 files changed

+93
-25
lines changed

2 files changed

+93
-25
lines changed

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

+92-24
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
//! Implementation of compiling the compiler and standard library, in "check"-based modes.
22
3+
use crate::core::build_steps::check;
34
use crate::core::build_steps::compile::{
45
add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo, std_crates_for_run_make,
56
};
@@ -9,7 +10,7 @@ use crate::core::builder::{
910
};
1011
use crate::core::config::TargetSelection;
1112
use crate::utils::build_stamp::{self, BuildStamp};
12-
use crate::{Mode, Subcommand};
13+
use crate::{Compiler, Mode, Subcommand};
1314

1415
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
1516
pub struct Std {
@@ -27,17 +28,25 @@ pub struct Std {
2728
/// passing `Builder::kind` to cargo invocations would run clippy on the entire compiler and library,
2829
/// which is not useful if we only want to lint a few crates with specific rules.
2930
override_build_kind: Option<Kind>,
31+
32+
override_compiler: Option<Compiler>,
3033
}
3134

3235
impl Std {
3336
pub fn new(target: TargetSelection) -> Self {
34-
Self { target, crates: vec![], override_build_kind: None }
37+
Self { target, crates: vec![], override_build_kind: None, override_compiler: None }
3538
}
3639

3740
pub fn build_kind(mut self, kind: Option<Kind>) -> Self {
3841
self.override_build_kind = kind;
3942
self
4043
}
44+
45+
/// Override the compiler used. Needed when checking tools that use [`Mode::ToolStd`].
46+
pub fn with_compiler(mut self, compiler: Compiler) -> Self {
47+
self.override_compiler = Some(compiler);
48+
self
49+
}
4150
}
4251

4352
impl Step for Std {
@@ -53,14 +62,21 @@ impl Step for Std {
5362

5463
fn make_run(run: RunConfig<'_>) {
5564
let crates = std_crates_for_run_make(&run);
56-
run.builder.ensure(Std { target: run.target, crates, override_build_kind: None });
65+
run.builder.ensure(Std {
66+
target: run.target,
67+
crates,
68+
override_build_kind: None,
69+
override_compiler: None,
70+
});
5771
}
5872

5973
fn run(self, builder: &Builder<'_>) {
6074
builder.require_submodule("library/stdarch", None);
6175

6276
let target = self.target;
63-
let compiler = builder.compiler(builder.top_stage, builder.config.build);
77+
let compiler = self
78+
.override_compiler
79+
.unwrap_or_else(|| builder.compiler(builder.top_stage, builder.config.build));
6480

6581
let mut cargo = builder::Cargo::new(
6682
builder,
@@ -375,6 +391,8 @@ macro_rules! tool_check_step {
375391
// The part of this path after the final '/' is also used as a display name.
376392
path: $path:literal
377393
$(, alt_path: $alt_path:literal )*
394+
, mode: $mode:path
395+
$(, allow_features: $allow_features:expr )?
378396
$(, default: $default:literal )?
379397
$( , )?
380398
}
@@ -400,7 +418,14 @@ macro_rules! tool_check_step {
400418

401419
fn run(self, builder: &Builder<'_>) {
402420
let Self { target } = self;
403-
run_tool_check_step(builder, target, stringify!($name), $path);
421+
422+
let allow_features = {
423+
let mut _value = "";
424+
$( _value = $allow_features; )?
425+
_value
426+
};
427+
428+
run_tool_check_step(builder, target, $path, $mode, allow_features);
404429
}
405430
}
406431
}
@@ -410,18 +435,38 @@ macro_rules! tool_check_step {
410435
fn run_tool_check_step(
411436
builder: &Builder<'_>,
412437
target: TargetSelection,
413-
step_type_name: &str,
414438
path: &str,
439+
mode: Mode,
440+
allow_features: &str,
415441
) {
416442
let display_name = path.rsplit('/').next().unwrap();
417-
let compiler = builder.compiler(builder.top_stage, builder.config.build);
418443

419-
builder.ensure(Rustc::new(target, builder));
444+
let host = builder.config.build;
445+
let compiler;
446+
447+
match mode {
448+
Mode::ToolBootstrap => {
449+
// Most "bootstrap tools" just need the bootstrap compiler.
450+
compiler = builder.compiler(0, host);
451+
}
452+
Mode::ToolStd => {
453+
// A small number of bootstrap tools also rely on in-tree standard
454+
// library crates (e.g. compiletest needs libtest), so we use the
455+
// bootstrap compiler to do a check build of the standard library.
456+
compiler = builder.compiler(0, host);
457+
builder.ensure(check::Std::new(target).with_compiler(compiler));
458+
}
459+
Mode::ToolRustc => {
460+
compiler = builder.compiler(builder.top_stage, host);
461+
builder.ensure(check::Rustc::new(target, builder));
462+
}
463+
_ => panic!("unexpected mode for tool check step: {mode:?}"),
464+
}
420465

421466
let mut cargo = prepare_tool_cargo(
422467
builder,
423468
compiler,
424-
Mode::ToolRustc,
469+
mode,
425470
target,
426471
builder.kind,
427472
path,
@@ -432,39 +477,62 @@ fn run_tool_check_step(
432477
SourceType::InTree,
433478
&[],
434479
);
480+
cargo.allow_features(allow_features);
435481

436482
// For ./x.py clippy, don't run with --all-targets because
437483
// linting tests and benchmarks can produce very noisy results
438484
if builder.kind != Kind::Clippy {
439485
cargo.arg("--all-targets");
440486
}
441487

442-
let stamp = BuildStamp::new(&builder.cargo_out(compiler, Mode::ToolRustc, target))
443-
.with_prefix(&format!("{}-check", step_type_name.to_lowercase()));
488+
let stamp = BuildStamp::new(&builder.cargo_out(compiler, mode, target))
489+
.with_prefix(&format!("{display_name}-check"));
444490

445-
let _guard = builder.msg_check(format!("{display_name} artifacts"), target);
491+
let _guard =
492+
builder.msg_tool(builder.kind, mode, display_name, compiler.stage, &compiler.host, &target);
446493
run_cargo(builder, cargo, builder.config.free_args.clone(), &stamp, vec![], true, false);
447494
}
448495

449-
tool_check_step!(Rustdoc { path: "src/tools/rustdoc", alt_path: "src/librustdoc" });
496+
// FIXME: Some of these `Mode::ToolRustc` values might be wrong.
497+
// (Historically, all tools were hardcoded to use `Mode::ToolRustc`.)
498+
499+
tool_check_step!(Rustdoc {
500+
path: "src/tools/rustdoc",
501+
alt_path: "src/librustdoc",
502+
mode: Mode::ToolRustc,
503+
});
450504
// Clippy, miri and Rustfmt are hybrids. They are external tools, but use a git subtree instead
451505
// of a submodule. Since the SourceType only drives the deny-warnings
452506
// behavior, treat it as in-tree so that any new warnings in clippy will be
453507
// rejected.
454-
tool_check_step!(Clippy { path: "src/tools/clippy" });
455-
tool_check_step!(Miri { path: "src/tools/miri" });
456-
tool_check_step!(CargoMiri { path: "src/tools/miri/cargo-miri" });
457-
tool_check_step!(Rustfmt { path: "src/tools/rustfmt" });
458-
tool_check_step!(MiroptTestTools { path: "src/tools/miropt-test-tools" });
459-
tool_check_step!(TestFloatParse { path: "src/etc/test-float-parse" });
460-
tool_check_step!(FeaturesStatusDump { path: "src/tools/features-status-dump" });
461-
462-
tool_check_step!(Bootstrap { path: "src/bootstrap", default: false });
508+
tool_check_step!(Clippy { path: "src/tools/clippy", mode: Mode::ToolRustc });
509+
tool_check_step!(Miri { path: "src/tools/miri", mode: Mode::ToolRustc });
510+
tool_check_step!(CargoMiri { path: "src/tools/miri/cargo-miri", mode: Mode::ToolRustc });
511+
tool_check_step!(Rustfmt { path: "src/tools/rustfmt", mode: Mode::ToolRustc });
512+
tool_check_step!(MiroptTestTools { path: "src/tools/miropt-test-tools", mode: Mode::ToolRustc });
513+
tool_check_step!(TestFloatParse { path: "src/etc/test-float-parse", mode: Mode::ToolRustc });
514+
tool_check_step!(FeaturesStatusDump {
515+
path: "src/tools/features-status-dump",
516+
mode: Mode::ToolRustc,
517+
});
518+
519+
tool_check_step!(Bootstrap { path: "src/bootstrap", mode: Mode::ToolBootstrap, default: false });
463520

464521
// `run-make-support` will be built as part of suitable run-make compiletest test steps, but support
465522
// check to make it easier to work on.
466-
tool_check_step!(RunMakeSupport { path: "src/tools/run-make-support", default: false });
523+
tool_check_step!(RunMakeSupport {
524+
path: "src/tools/run-make-support",
525+
mode: Mode::ToolBootstrap,
526+
default: false,
527+
});
467528

468529
// Compiletest is implicitly "checked" when it gets built in order to run tests,
469530
// so this is mainly for people working on compiletest to run locally.
470-
tool_check_step!(Compiletest { path: "src/tools/compiletest", default: false });
531+
//
532+
// Compiletest uses libtest internally, so it needs `Mode::ToolStd` and `#![feature(test)]`.
533+
tool_check_step!(Compiletest {
534+
path: "src/tools/compiletest",
535+
mode: Mode::ToolStd,
536+
allow_features: "test",
537+
default: false,
538+
});

src/bootstrap/src/core/build_steps/tool.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ impl Builder<'_> {
7878
*target,
7979
),
8080
// doesn't depend on compiler, same as host compiler
81-
_ => self.msg(Kind::Build, build_stage, format_args!("tool {tool}"), *host, *target),
81+
_ => self.msg(kind, build_stage, format_args!("tool {tool}"), *host, *target),
8282
}
8383
}
8484
}

0 commit comments

Comments
 (0)