Skip to content

Add ToolTarget to bootstrap #143641

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 12 commits into from
Jul 19, 2025
5 changes: 3 additions & 2 deletions src/bootstrap/src/core/build_steps/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@ use crate::core::build_steps::compile::{
};
use crate::core::build_steps::tool;
use crate::core::build_steps::tool::{
COMPILETEST_ALLOW_FEATURES, SourceType, get_compiler_for_target, prepare_tool_cargo,
COMPILETEST_ALLOW_FEATURES, SourceType, ToolTargetBuildMode, get_tool_target_compiler,
prepare_tool_cargo,
};
use crate::core::builder::{
self, Alias, Builder, Kind, RunConfig, ShouldRun, Step, StepMetadata, crate_description,
Expand Down Expand Up @@ -252,7 +253,7 @@ fn prepare_compiler_for_check(

match mode {
Mode::ToolBootstrap => builder.compiler(0, host),
Mode::ToolTarget => get_compiler_for_target(builder, target),
Mode::ToolTarget => get_tool_target_compiler(builder, ToolTargetBuildMode::Build(target)),
Mode::ToolStd => {
// These tools require the local standard library to be checked
let build_compiler = builder.compiler(builder.top_stage, host);
Expand Down
14 changes: 6 additions & 8 deletions src/bootstrap/src/core/build_steps/compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2286,15 +2286,13 @@ impl Step for Assemble {
}

// In addition to `rust-lld` also install `wasm-component-ld` when
// LLD is enabled. This is a relatively small binary that primarily
// delegates to the `rust-lld` binary for linking and then runs
// logic to create the final binary. This is used by the
// `wasm32-wasip2` target of Rust.
// is enabled. This is used by the `wasm32-wasip2` target of Rust.
if builder.tool_enabled("wasm-component-ld") {
let wasm_component = builder.ensure(crate::core::build_steps::tool::WasmComponentLd {
compiler: build_compiler,
target: target_compiler.host,
});
let wasm_component =
builder.ensure(crate::core::build_steps::tool::WasmComponentLd::for_compiler(
builder,
target_compiler,
));
builder.copy_link(
&wasm_component.tool_path,
&libdir_bin.join(wasm_component.tool_path.file_name().unwrap()),
Expand Down
107 changes: 101 additions & 6 deletions src/bootstrap/src/core/build_steps/tool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -365,12 +365,36 @@ pub(crate) fn get_tool_rustc_compiler(
builder.compiler(target_compiler.stage.saturating_sub(1), builder.config.host_target)
}

/// Returns the smallest stage compiler that is able to compile code for the given `target`.
pub(crate) fn get_compiler_for_target(builder: &Builder<'_>, target: TargetSelection) -> Compiler {
/// Determines how to build a `ToolTarget`, i.e. which compiler should be used to compile it.
/// The compiler stage is automatically auto-bumped if we need to cross-compile a stage 1 tool.
pub enum ToolTargetBuildMode {
/// Build the tool using rustc that corresponds to the selected CLI stage.
Build(TargetSelection),
/// Build the tool so that it can be attached to the sysroot of the passed compiler.
/// Since we always dist stage 2+, the compiler that builds the tool in this case has to be
/// stage 1+.
Dist(Compiler),
}

/// Returns compiler that is able to compile a `ToolTarget` tool with the given `mode`.
pub(crate) fn get_tool_target_compiler(
builder: &Builder<'_>,
mode: ToolTargetBuildMode,
) -> Compiler {
let (target, min_build_compiler_stage) = match mode {
ToolTargetBuildMode::Build(target) => {
assert!(builder.top_stage > 0);
(target, builder.top_stage - 1)
}
ToolTargetBuildMode::Dist(target_compiler) => {
assert!(target_compiler.stage > 0);
(target_compiler.host, target_compiler.stage - 1)
}
};
let compiler = if builder.host_target == target {
builder.compiler(0, builder.host_target)
builder.compiler(min_build_compiler_stage, builder.host_target)
} else {
builder.compiler(1, builder.host_target)
builder.compiler(min_build_compiler_stage.max(1), builder.host_target)
};
builder.std(compiler, target);
compiler
Expand Down Expand Up @@ -533,7 +557,6 @@ bootstrap_tool!(
// rustdoc-gui-test has a crate dependency on compiletest, so it needs the same unstable features.
RustdocGUITest, "src/tools/rustdoc-gui-test", "rustdoc-gui-test", is_unstable_tool = true, allow_features = COMPILETEST_ALLOW_FEATURES;
CoverageDump, "src/tools/coverage-dump", "coverage-dump";
WasmComponentLd, "src/tools/wasm-component-ld", "wasm-component-ld", is_unstable_tool = true, allow_features = "min_specialization";
UnicodeTableGenerator, "src/tools/unicode-table-generator", "unicode-table-generator";
FeaturesStatusDump, "src/tools/features-status-dump", "features-status-dump";
OptimizedDist, "src/tools/opt-dist", "opt-dist", submodules = &["src/tools/rustc-perf"];
Expand Down Expand Up @@ -661,7 +684,10 @@ impl Step for RemoteTestServer {

fn make_run(run: RunConfig<'_>) {
run.builder.ensure(RemoteTestServer {
build_compiler: get_compiler_for_target(run.builder, run.target),
build_compiler: get_tool_target_compiler(
run.builder,
ToolTargetBuildMode::Build(run.target),
),
target: run.target,
});
}
Expand Down Expand Up @@ -935,6 +961,75 @@ impl Step for LldWrapper {
}
}

/// Builds the `wasm-component-ld` linker wrapper, which is shipped with rustc to be executed on the
/// host platform where rustc runs.
#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct WasmComponentLd {
build_compiler: Compiler,
target: TargetSelection,
}

impl WasmComponentLd {
/// Returns `WasmComponentLd` that should be **used** by the passed compiler.
pub fn for_compiler(builder: &Builder<'_>, target_compiler: Compiler) -> Self {
Self {
build_compiler: get_tool_target_compiler(
builder,
ToolTargetBuildMode::Dist(target_compiler),
),
target: target_compiler.host,
}
}
}

impl Step for WasmComponentLd {
type Output = ToolBuildResult;

const ONLY_HOSTS: bool = true;

fn should_run(run: ShouldRun<'_>) -> ShouldRun<'_> {
run.path("src/tools/wasm-component-ld")
}

fn make_run(run: RunConfig<'_>) {
run.builder.ensure(WasmComponentLd {
build_compiler: get_tool_target_compiler(
run.builder,
ToolTargetBuildMode::Build(run.target),
),
target: run.target,
});
}

#[cfg_attr(
feature = "tracing",
instrument(
level = "debug",
name = "WasmComponentLd::run",
skip_all,
fields(build_compiler = ?self.build_compiler),
),
)]
fn run(self, builder: &Builder<'_>) -> ToolBuildResult {
builder.ensure(ToolBuild {
build_compiler: self.build_compiler,
target: self.target,
tool: "wasm-component-ld",
mode: Mode::ToolTarget,
path: "src/tools/wasm-component-ld",
source_type: SourceType::InTree,
extra_features: vec![],
allow_features: "min-specialization",
cargo_args: vec![],
artifact_kind: ToolArtifactKind::Binary,
})
}

fn metadata(&self) -> Option<StepMetadata> {
Some(StepMetadata::build("WasmComponentLd", self.target).built_by(self.build_compiler))
}
}

#[derive(Debug, Clone, Hash, PartialEq, Eq)]
pub struct RustAnalyzer {
pub compiler: Compiler,
Expand Down
1 change: 1 addition & 0 deletions src/bootstrap/src/core/builder/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -981,6 +981,7 @@ impl<'a> Builder<'a> {
tool::CoverageDump,
tool::LlvmBitcodeLinker,
tool::RustcPerf,
tool::WasmComponentLd
),
Kind::Clippy => describe!(
clippy::Std,
Expand Down