Skip to content

Commit 63f7241

Browse files
committed
Introduce ToolTarget for cross-compilable tools that can be built with the stage0 compiler
1 parent e8be2d8 commit 63f7241

File tree

5 files changed

+74
-21
lines changed

5 files changed

+74
-21
lines changed

src/bootstrap/README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -105,7 +105,7 @@ build/
105105
debuginfo/
106106
...
107107

108-
# Bootstrap host tools (which are always compiled with the stage0 compiler)
108+
# Host tools (which are always compiled with the stage0 compiler)
109109
# are stored here.
110110
bootstrap-tools/
111111

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

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ use crate::core::build_steps::compile::{
44
add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo, std_crates_for_run_make,
55
};
66
use crate::core::build_steps::tool;
7-
use crate::core::build_steps::tool::{COMPILETEST_ALLOW_FEATURES, SourceType, prepare_tool_cargo};
7+
use crate::core::build_steps::tool::{
8+
COMPILETEST_ALLOW_FEATURES, SourceType, get_tool_target_compiler, prepare_tool_cargo,
9+
};
810
use crate::core::builder::{
911
self, Alias, Builder, Kind, RunConfig, ShouldRun, Step, StepMetadata, crate_description,
1012
};
@@ -247,8 +249,10 @@ fn prepare_compiler_for_check(
247249
mode: Mode,
248250
) -> Compiler {
249251
let host = builder.host_target;
252+
250253
match mode {
251254
Mode::ToolBootstrap => builder.compiler(0, host),
255+
Mode::ToolTarget => get_tool_target_compiler(builder, target),
252256
Mode::ToolStd => {
253257
// These tools require the local standard library to be checked
254258
let build_compiler = builder.compiler(builder.top_stage, host);

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

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,16 @@ pub(crate) fn get_tool_rustc_compiler(
365365
builder.compiler(target_compiler.stage.saturating_sub(1), builder.config.host_target)
366366
}
367367

368+
/// Returns a compiler that is able to compile a `ToolTarget` tool for the given `target`.
369+
pub(crate) fn get_tool_target_compiler(builder: &Builder<'_>, target: TargetSelection) -> Compiler {
370+
if builder.host_target == target {
371+
builder.compiler(0, builder.host_target)
372+
} else {
373+
// FIXME: should this be builder.top_stage to avoid rebuilds?
374+
builder.compiler(1, target)
375+
}
376+
}
377+
368378
/// Links a built tool binary with the given `name` from the build directory to the
369379
/// tools directory.
370380
fn copy_link_tool_bin(

src/bootstrap/src/core/builder/cargo.rs

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -672,7 +672,7 @@ impl Builder<'_> {
672672
}
673673

674674
match mode {
675-
Mode::Std | Mode::ToolBootstrap | Mode::ToolStd => {}
675+
Mode::Std | Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolTarget => {}
676676
Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {
677677
// Build proc macros both for the host and the target unless proc-macros are not
678678
// supported by the target.
@@ -714,7 +714,7 @@ impl Builder<'_> {
714714
// feature on the rustc side.
715715
cargo.arg("-Zbinary-dep-depinfo");
716716
let allow_features = match mode {
717-
Mode::ToolBootstrap | Mode::ToolStd => {
717+
Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolTarget => {
718718
// Restrict the allowed features so we don't depend on nightly
719719
// accidentally.
720720
//
@@ -867,7 +867,7 @@ impl Builder<'_> {
867867
let debuginfo_level = match mode {
868868
Mode::Rustc | Mode::Codegen => self.config.rust_debuginfo_level_rustc,
869869
Mode::Std => self.config.rust_debuginfo_level_std,
870-
Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolRustc => {
870+
Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolRustc | Mode::ToolTarget => {
871871
self.config.rust_debuginfo_level_tools
872872
}
873873
};
@@ -879,11 +879,10 @@ impl Builder<'_> {
879879
profile_var("DEBUG_ASSERTIONS"),
880880
match mode {
881881
Mode::Std => self.config.std_debug_assertions,
882-
Mode::Rustc => self.config.rustc_debug_assertions,
883-
Mode::Codegen => self.config.rustc_debug_assertions,
884-
Mode::ToolBootstrap => self.config.tools_debug_assertions,
885-
Mode::ToolStd => self.config.tools_debug_assertions,
886-
Mode::ToolRustc => self.config.tools_debug_assertions,
882+
Mode::Rustc | Mode::Codegen => self.config.rustc_debug_assertions,
883+
Mode::ToolBootstrap | Mode::ToolStd | Mode::ToolRustc | Mode::ToolTarget => {
884+
self.config.tools_debug_assertions
885+
}
887886
}
888887
.to_string(),
889888
);
@@ -954,7 +953,11 @@ impl Builder<'_> {
954953
cargo.env("CFG_VIRTUAL_RUSTC_DEV_SOURCE_BASE_DIR", map_to);
955954
}
956955
}
957-
Mode::Std | Mode::ToolBootstrap | Mode::ToolRustc | Mode::ToolStd => {
956+
Mode::Std
957+
| Mode::ToolBootstrap
958+
| Mode::ToolRustc
959+
| Mode::ToolStd
960+
| Mode::ToolTarget => {
958961
if let Some(ref map_to) =
959962
self.build.debuginfo_map_to(GitRepo::Rustc, RemapScheme::NonCompiler)
960963
{

src/bootstrap/src/lib.rs

Lines changed: 46 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -253,12 +253,26 @@ pub enum Mode {
253253
/// These tools are intended to be only executed on the host system that
254254
/// invokes bootstrap, and they thus cannot be cross-compiled.
255255
///
256-
/// They are always built using the stage0 compiler, and typically they
256+
/// They are always built using the stage0 compiler, and they
257257
/// can be compiled with stable Rust.
258258
///
259259
/// These tools also essentially do not participate in staging.
260260
ToolBootstrap,
261261

262+
/// Build a cross-compilable helper tool.
263+
/// - If we compile it for the host, we use the stage0 compiler.
264+
/// - If we compile it for another target, we use local compiler (because stage0 does not have
265+
/// stdlib for the tool available for other targets).
266+
///
267+
/// This mode exists to avoid needless (re)builds of tools that can be compiled with
268+
/// a stable/stage0 compiler. It essentially behaves as `ToolBootstrap` when not
269+
/// cross-compiling, and as `ToolStd` when cross-compiling.
270+
///
271+
/// It is used e.g. for linkers and linker tools invoked by rustc on its host target.
272+
///
273+
/// These tools participate in staging only when required for cross-compilation.
274+
ToolTarget,
275+
262276
/// Build a tool which uses the locally built std, placing output in the
263277
/// "stageN-tools" directory. Its usage is quite rare, mainly used by
264278
/// compiletest which needs libtest.
@@ -804,17 +818,39 @@ impl Build {
804818
/// stage when running with a particular host compiler.
805819
///
806820
/// The mode indicates what the root directory is for.
807-
fn stage_out(&self, compiler: Compiler, mode: Mode) -> PathBuf {
808-
let suffix = match mode {
809-
Mode::Std => "-std",
810-
Mode::Rustc => "-rustc",
811-
Mode::Codegen => "-codegen",
812-
Mode::ToolBootstrap => {
813-
return self.out.join(compiler.host).join("bootstrap-tools");
821+
fn stage_out(&self, build_compiler: Compiler, mode: Mode) -> PathBuf {
822+
use std::fmt::Write;
823+
824+
fn bootstrap_tool() -> (Option<u32>, &'static str) {
825+
(None, "bootstrap-tools")
826+
}
827+
fn staged_tool(build_compiler: Compiler) -> (Option<u32>, &'static str) {
828+
(Some(build_compiler.stage), "tools")
829+
}
830+
831+
let (stage, suffix) = match mode {
832+
Mode::Std => (Some(build_compiler.stage), "std"),
833+
Mode::Rustc => (Some(build_compiler.stage), "rustc"),
834+
Mode::Codegen => (Some(build_compiler.stage), "codegen"),
835+
Mode::ToolBootstrap => bootstrap_tool(),
836+
Mode::ToolStd | Mode::ToolRustc => (Some(build_compiler.stage), "tools"),
837+
Mode::ToolTarget => {
838+
// If we're not cross-compiling (the common case), share the target directory with
839+
// bootstrap tools to reuse the build cache.
840+
if build_compiler.stage == 0 {
841+
bootstrap_tool()
842+
} else {
843+
staged_tool(build_compiler)
844+
}
814845
}
815-
Mode::ToolStd | Mode::ToolRustc => "-tools",
816846
};
817-
self.out.join(compiler.host).join(format!("stage{}{}", compiler.stage, suffix))
847+
let path = self.out.join(build_compiler.host);
848+
let mut dir_name = String::new();
849+
if let Some(stage) = stage {
850+
write!(dir_name, "stage{stage}-").unwrap();
851+
}
852+
dir_name.push_str(suffix);
853+
path.join(dir_name)
818854
}
819855

820856
/// Returns the root output directory for all Cargo output in a given stage,

0 commit comments

Comments
 (0)