Add Builder::std method for building a standard library
This commit is contained in:
parent
58d5e11690
commit
450a2d8dc1
10 changed files with 84 additions and 41 deletions
|
|
@ -1,6 +1,5 @@
|
|||
//! Implementation of compiling the compiler and standard library, in "check"-based modes.
|
||||
|
||||
use crate::core::build_steps::compile;
|
||||
use crate::core::build_steps::compile::{
|
||||
add_to_sysroot, run_cargo, rustc_cargo, rustc_cargo_env, std_cargo, std_crates_for_run_make,
|
||||
};
|
||||
|
|
@ -89,7 +88,7 @@ impl Step for Std {
|
|||
}
|
||||
|
||||
// Reuse the stage0 libstd
|
||||
builder.ensure(compile::Std::new(compiler, target));
|
||||
builder.std(compiler, target);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
@ -223,8 +222,8 @@ impl Step for Rustc {
|
|||
// the sysroot for the compiler to find. Otherwise, we're going to
|
||||
// fail when building crates that need to generate code (e.g., build
|
||||
// scripts and their dependencies).
|
||||
builder.ensure(crate::core::build_steps::compile::Std::new(compiler, compiler.host));
|
||||
builder.ensure(crate::core::build_steps::compile::Std::new(compiler, target));
|
||||
builder.std(compiler, compiler.host);
|
||||
builder.std(compiler, target);
|
||||
} else {
|
||||
builder.ensure(Std::new(target));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,8 @@
|
|||
//! Implementation of running clippy on the compiler, standard library and various tools.
|
||||
|
||||
use super::check;
|
||||
use super::compile::{run_cargo, rustc_cargo, std_cargo};
|
||||
use super::tool::{SourceType, prepare_tool_cargo};
|
||||
use super::{check, compile};
|
||||
use crate::builder::{Builder, ShouldRun};
|
||||
use crate::core::build_steps::compile::std_crates_for_run_make;
|
||||
use crate::core::builder;
|
||||
|
|
@ -214,8 +214,8 @@ impl Step for Rustc {
|
|||
// the sysroot for the compiler to find. Otherwise, we're going to
|
||||
// fail when building crates that need to generate code (e.g., build
|
||||
// scripts and their dependencies).
|
||||
builder.ensure(compile::Std::new(compiler, compiler.host));
|
||||
builder.ensure(compile::Std::new(compiler, target));
|
||||
builder.std(compiler, compiler.host);
|
||||
builder.std(compiler, target);
|
||||
} else {
|
||||
builder.ensure(check::Std::new(target));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -213,7 +213,7 @@ impl Step for Std {
|
|||
{
|
||||
trace!(?compiler_to_use, ?compiler, "compiler != compiler_to_use, uplifting library");
|
||||
|
||||
builder.ensure(Std::new(compiler_to_use, target));
|
||||
builder.std(compiler_to_use, target);
|
||||
let msg = if compiler_to_use.host == target {
|
||||
format!(
|
||||
"Uplifting library (stage{} -> stage{})",
|
||||
|
|
@ -690,7 +690,7 @@ pub fn std_cargo(builder: &Builder<'_>, target: TargetSelection, stage: u32, car
|
|||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq, Hash)]
|
||||
struct StdLink {
|
||||
pub struct StdLink {
|
||||
pub compiler: Compiler,
|
||||
pub target_compiler: Compiler,
|
||||
pub target: TargetSelection,
|
||||
|
|
@ -701,7 +701,7 @@ struct StdLink {
|
|||
}
|
||||
|
||||
impl StdLink {
|
||||
fn from_std(std: Std, host_compiler: Compiler) -> Self {
|
||||
pub fn from_std(std: Std, host_compiler: Compiler) -> Self {
|
||||
Self {
|
||||
compiler: host_compiler,
|
||||
target_compiler: std.compiler,
|
||||
|
|
@ -1067,7 +1067,7 @@ impl Step for Rustc {
|
|||
|
||||
// Build a standard library for `target` using the `build_compiler`.
|
||||
// This will be the standard library that the rustc which we build *links to*.
|
||||
builder.ensure(Std::new(build_compiler, target));
|
||||
builder.std(build_compiler, target);
|
||||
|
||||
if builder.config.keep_stage.contains(&build_compiler.stage) {
|
||||
trace!(stage = build_compiler.stage, "`keep-stage` requested");
|
||||
|
|
@ -1108,10 +1108,10 @@ impl Step for Rustc {
|
|||
// build scripts and proc macros.
|
||||
// If we are not cross-compiling, the Std build above will be the same one as the one we
|
||||
// prepare here.
|
||||
builder.ensure(Std::new(
|
||||
builder.std(
|
||||
builder.compiler(self.build_compiler.stage, builder.config.host_target),
|
||||
builder.config.host_target,
|
||||
));
|
||||
);
|
||||
|
||||
let mut cargo = builder::Cargo::new(
|
||||
builder,
|
||||
|
|
@ -2079,7 +2079,7 @@ impl Step for Assemble {
|
|||
if builder.download_rustc() {
|
||||
trace!("`download-rustc` requested, reusing CI compiler for stage > 0");
|
||||
|
||||
builder.ensure(Std::new(target_compiler, target_compiler.host));
|
||||
builder.std(target_compiler, target_compiler.host);
|
||||
let sysroot =
|
||||
builder.ensure(Sysroot { compiler: target_compiler, force_recompile: false });
|
||||
// Ensure that `libLLVM.so` ends up in the newly created target directory,
|
||||
|
|
@ -2087,7 +2087,7 @@ impl Step for Assemble {
|
|||
dist::maybe_install_llvm_target(builder, target_compiler.host, &sysroot);
|
||||
// Lower stages use `ci-rustc-sysroot`, not stageN
|
||||
if target_compiler.stage == builder.top_stage {
|
||||
builder.info(&format!("Creating a sysroot for stage{stage} compiler (use `rustup toolchain link 'name' build/host/stage{stage}`)", stage=target_compiler.stage));
|
||||
builder.info(&format!("Creating a sysroot for stage{stage} compiler (use `rustup toolchain link 'name' build/host/stage{stage}`)", stage = target_compiler.stage));
|
||||
}
|
||||
|
||||
let mut precompiled_compiler = target_compiler;
|
||||
|
|
|
|||
|
|
@ -711,7 +711,7 @@ impl Step for Std {
|
|||
return None;
|
||||
}
|
||||
|
||||
builder.ensure(compile::Std::new(compiler, target));
|
||||
builder.std(compiler, target);
|
||||
|
||||
let mut tarball = Tarball::new(builder, "rust-std", &target.triple);
|
||||
tarball.include_target_in_component_name(true);
|
||||
|
|
|
|||
|
|
@ -804,7 +804,7 @@ impl Step for Rustc {
|
|||
// Build the standard library, so that proc-macros can use it.
|
||||
// (Normally, only the metadata would be necessary, but proc-macros are special since they run at compile-time.)
|
||||
let compiler = builder.compiler(stage, builder.config.host_target);
|
||||
builder.ensure(compile::Std::new(compiler, builder.config.host_target));
|
||||
builder.std(compiler, builder.config.host_target);
|
||||
|
||||
let _guard = builder.msg_sysroot_tool(
|
||||
Kind::Doc,
|
||||
|
|
@ -947,7 +947,7 @@ macro_rules! tool_doc {
|
|||
t!(fs::create_dir_all(&out));
|
||||
|
||||
let compiler = builder.compiler(stage, builder.config.host_target);
|
||||
builder.ensure(compile::Std::new(compiler, target));
|
||||
builder.std(compiler, target);
|
||||
|
||||
if true $(&& $rustc_tool)? {
|
||||
// Build rustc docs so that we generate relative links.
|
||||
|
|
@ -1195,7 +1195,7 @@ impl Step for RustcBook {
|
|||
let rustc = builder.rustc(self.compiler);
|
||||
// The tool runs `rustc` for extracting output examples, so it needs a
|
||||
// functional sysroot.
|
||||
builder.ensure(compile::Std::new(self.compiler, self.target));
|
||||
builder.std(self.compiler, self.target);
|
||||
let mut cmd = builder.tool_cmd(Tool::LintDocs);
|
||||
cmd.arg("--src");
|
||||
cmd.arg(builder.src.join("compiler"));
|
||||
|
|
@ -1272,7 +1272,7 @@ impl Step for Reference {
|
|||
|
||||
// This is needed for generating links to the standard library using
|
||||
// the mdbook-spec plugin.
|
||||
builder.ensure(compile::Std::new(self.compiler, builder.config.host_target));
|
||||
builder.std(self.compiler, builder.config.host_target);
|
||||
|
||||
// Run rustbook/mdbook to generate the HTML pages.
|
||||
builder.ensure(RustbookSrc {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
use std::env::consts::EXE_EXTENSION;
|
||||
use std::fmt::{Display, Formatter};
|
||||
|
||||
use crate::core::build_steps::compile::{Std, Sysroot};
|
||||
use crate::core::build_steps::compile::Sysroot;
|
||||
use crate::core::build_steps::tool::{RustcPerf, Rustdoc};
|
||||
use crate::core::builder::Builder;
|
||||
use crate::core::config::DebuginfoLevel;
|
||||
|
|
@ -152,7 +152,7 @@ Consider setting `rust.debuginfo-level = 1` in `bootstrap.toml`."#);
|
|||
}
|
||||
|
||||
let compiler = builder.compiler(builder.top_stage, builder.config.host_target);
|
||||
builder.ensure(Std::new(compiler, builder.config.host_target));
|
||||
builder.std(compiler, builder.config.host_target);
|
||||
|
||||
if let Some(opts) = args.cmd.shared_opts()
|
||||
&& opts.profiles.contains(&Profile::Doc)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ use std::{env, fs, iter};
|
|||
|
||||
use clap_complete::shells;
|
||||
|
||||
use crate::core::build_steps::compile::run_cargo;
|
||||
use crate::core::build_steps::compile::{Std, run_cargo};
|
||||
use crate::core::build_steps::doc::DocumentationFormat;
|
||||
use crate::core::build_steps::gcc::{Gcc, add_cg_gcc_cargo_flags};
|
||||
use crate::core::build_steps::llvm::get_llvm_version;
|
||||
|
|
@ -544,7 +544,7 @@ impl Step for Miri {
|
|||
// We also need sysroots, for Miri and for the host (the latter for build scripts).
|
||||
// This is for the tests so everything is done with the target compiler.
|
||||
let miri_sysroot = Miri::build_miri_sysroot(builder, target_compiler, target);
|
||||
builder.ensure(compile::Std::new(target_compiler, host));
|
||||
builder.std(target_compiler, host);
|
||||
let host_sysroot = builder.sysroot(target_compiler);
|
||||
|
||||
// Miri has its own "target dir" for ui test dependencies. Make sure it gets cleared when
|
||||
|
|
@ -709,7 +709,7 @@ impl Step for CompiletestTest {
|
|||
|
||||
// We need `ToolStd` for the locally-built sysroot because
|
||||
// compiletest uses unstable features of the `test` crate.
|
||||
builder.ensure(compile::Std::new(compiler, host));
|
||||
builder.std(compiler, host);
|
||||
let mut cargo = tool::prepare_tool_cargo(
|
||||
builder,
|
||||
compiler,
|
||||
|
|
@ -1009,7 +1009,7 @@ impl Step for RustdocGUI {
|
|||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
builder.ensure(compile::Std::new(self.compiler, self.target));
|
||||
builder.std(self.compiler, self.target);
|
||||
|
||||
let mut cmd = builder.tool_cmd(Tool::RustdocGUITest);
|
||||
|
||||
|
|
@ -1634,7 +1634,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
|
|||
if suite == "mir-opt" {
|
||||
builder.ensure(compile::Std::new(compiler, compiler.host).is_for_mir_opt_tests(true));
|
||||
} else {
|
||||
builder.ensure(compile::Std::new(compiler, compiler.host));
|
||||
builder.std(compiler, compiler.host);
|
||||
}
|
||||
|
||||
let mut cmd = builder.tool_cmd(Tool::Compiletest);
|
||||
|
|
@ -1642,7 +1642,7 @@ NOTE: if you're sure you want to do this, please open an issue as to why. In the
|
|||
if suite == "mir-opt" {
|
||||
builder.ensure(compile::Std::new(compiler, target).is_for_mir_opt_tests(true));
|
||||
} else {
|
||||
builder.ensure(compile::Std::new(compiler, target));
|
||||
builder.std(compiler, target);
|
||||
}
|
||||
|
||||
builder.ensure(RemoteCopyLibs { compiler, target });
|
||||
|
|
@ -2177,7 +2177,7 @@ impl BookTest {
|
|||
fn run_ext_doc(self, builder: &Builder<'_>) {
|
||||
let compiler = self.compiler;
|
||||
|
||||
builder.ensure(compile::Std::new(compiler, compiler.host));
|
||||
builder.std(compiler, compiler.host);
|
||||
|
||||
// mdbook just executes a binary named "rustdoc", so we need to update
|
||||
// PATH so that it points to our rustdoc.
|
||||
|
|
@ -2263,7 +2263,7 @@ impl BookTest {
|
|||
let compiler = self.compiler;
|
||||
let host = self.compiler.host;
|
||||
|
||||
builder.ensure(compile::Std::new(compiler, host));
|
||||
builder.std(compiler, host);
|
||||
|
||||
let _guard =
|
||||
builder.msg(Kind::Test, compiler.stage, format!("book {}", self.name), host, host);
|
||||
|
|
@ -2410,7 +2410,7 @@ impl Step for ErrorIndex {
|
|||
drop(guard);
|
||||
// The tests themselves need to link to std, so make sure it is
|
||||
// available.
|
||||
builder.ensure(compile::Std::new(compiler, compiler.host));
|
||||
builder.std(compiler, compiler.host);
|
||||
markdown_test(builder, compiler, &output);
|
||||
}
|
||||
}
|
||||
|
|
@ -2473,7 +2473,7 @@ impl Step for CrateLibrustc {
|
|||
}
|
||||
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
builder.ensure(compile::Std::new(self.compiler, self.target));
|
||||
builder.std(self.compiler, self.target);
|
||||
|
||||
// To actually run the tests, delegate to a copy of the `Crate` step.
|
||||
builder.ensure(Crate {
|
||||
|
|
@ -2641,7 +2641,7 @@ impl Step for Crate {
|
|||
|
||||
// Prepare sysroot
|
||||
// See [field@compile::Std::force_recompile].
|
||||
builder.ensure(compile::Std::new(compiler, compiler.host).force_recompile(true));
|
||||
builder.ensure(Std::new(compiler, compiler.host).force_recompile(true));
|
||||
|
||||
// If we're not doing a full bootstrap but we're testing a stage2
|
||||
// version of libstd, then what we're actually testing is the libstd
|
||||
|
|
@ -2767,7 +2767,7 @@ impl Step for CrateRustdoc {
|
|||
// using `download-rustc`, the rustc_private artifacts may be in a *different sysroot* from
|
||||
// the target rustdoc (`ci-rustc-sysroot` vs `stage2`). In that case, we need to ensure this
|
||||
// explicitly to make sure it ends up in the stage2 sysroot.
|
||||
builder.ensure(compile::Std::new(compiler, target));
|
||||
builder.std(compiler, target);
|
||||
builder.ensure(compile::Rustc::new(compiler, target));
|
||||
|
||||
let mut cargo = tool::prepare_tool_cargo(
|
||||
|
|
@ -2911,7 +2911,7 @@ impl Step for RemoteCopyLibs {
|
|||
return;
|
||||
}
|
||||
|
||||
builder.ensure(compile::Std::new(compiler, target));
|
||||
builder.std(compiler, target);
|
||||
|
||||
builder.info(&format!("REMOTE copy libs to emulator ({target})"));
|
||||
|
||||
|
|
@ -3101,7 +3101,7 @@ impl Step for TierCheck {
|
|||
|
||||
/// Tests the Platform Support page in the rustc book.
|
||||
fn run(self, builder: &Builder<'_>) {
|
||||
builder.ensure(compile::Std::new(self.compiler, self.compiler.host));
|
||||
builder.std(self.compiler, self.compiler.host);
|
||||
let mut cargo = tool::prepare_tool_cargo(
|
||||
builder,
|
||||
self.compiler,
|
||||
|
|
@ -3334,7 +3334,7 @@ impl Step for CodegenCranelift {
|
|||
let compiler = self.compiler;
|
||||
let target = self.target;
|
||||
|
||||
builder.ensure(compile::Std::new(compiler, target));
|
||||
builder.std(compiler, target);
|
||||
|
||||
// If we're not doing a full bootstrap but we're testing a stage2
|
||||
// version of libstd, then what we're actually testing is the libstd
|
||||
|
|
|
|||
|
|
@ -122,14 +122,14 @@ impl Step for ToolBuild {
|
|||
Mode::ToolRustc => {
|
||||
// If compiler was forced, its artifacts should be prepared earlier.
|
||||
if !self.compiler.is_forced_compiler() {
|
||||
builder.ensure(compile::Std::new(self.compiler, self.compiler.host));
|
||||
builder.std(self.compiler, self.compiler.host);
|
||||
builder.ensure(compile::Rustc::new(self.compiler, target));
|
||||
}
|
||||
}
|
||||
Mode::ToolStd => {
|
||||
// If compiler was forced, its artifacts should be prepared earlier.
|
||||
if !self.compiler.is_forced_compiler() {
|
||||
builder.ensure(compile::Std::new(self.compiler, target))
|
||||
builder.std(self.compiler, target)
|
||||
}
|
||||
}
|
||||
Mode::ToolBootstrap => {} // uses downloaded stage0 compiler libs
|
||||
|
|
|
|||
|
|
@ -3,8 +3,8 @@ use std::ffi::{OsStr, OsString};
|
|||
use std::path::{Path, PathBuf};
|
||||
|
||||
use super::{Builder, Kind};
|
||||
use crate::core::build_steps::test;
|
||||
use crate::core::build_steps::tool::SourceType;
|
||||
use crate::core::build_steps::{compile, test};
|
||||
use crate::core::config::SplitDebuginfo;
|
||||
use crate::core::config::flags::Color;
|
||||
use crate::utils::build_stamp;
|
||||
|
|
@ -842,7 +842,7 @@ impl Builder<'_> {
|
|||
|
||||
// If this is for `miri-test`, prepare the sysroots.
|
||||
if cmd_kind == Kind::MiriTest {
|
||||
self.ensure(compile::Std::new(compiler, compiler.host));
|
||||
self.std(compiler, compiler.host);
|
||||
let host_sysroot = self.sysroot(compiler);
|
||||
let miri_sysroot = test::Miri::build_miri_sysroot(self, compiler, target);
|
||||
cargo.env("MIRI_SYSROOT", &miri_sysroot);
|
||||
|
|
|
|||
|
|
@ -15,6 +15,7 @@ use tracing::instrument;
|
|||
|
||||
pub use self::cargo::{Cargo, cargo_profile_var};
|
||||
pub use crate::Compiler;
|
||||
use crate::core::build_steps::compile::{Std, StdLink};
|
||||
use crate::core::build_steps::{
|
||||
check, clean, clippy, compile, dist, doc, gcc, install, llvm, run, setup, test, tool, vendor,
|
||||
};
|
||||
|
|
@ -1350,6 +1351,49 @@ impl<'a> Builder<'a> {
|
|||
resolved_compiler
|
||||
}
|
||||
|
||||
/// Obtain a standard library for the given target that will be built by the passed compiler.
|
||||
/// The standard library will be linked to the sysroot of the passed compiler.
|
||||
///
|
||||
/// Prefer using this method rather than manually invoking `Std::new`.
|
||||
#[cfg_attr(
|
||||
feature = "tracing",
|
||||
instrument(
|
||||
level = "trace",
|
||||
name = "Builder::std",
|
||||
target = "STD",
|
||||
skip_all,
|
||||
fields(
|
||||
compiler = ?compiler,
|
||||
target = ?target,
|
||||
),
|
||||
),
|
||||
)]
|
||||
pub fn std(&self, compiler: Compiler, target: TargetSelection) {
|
||||
// FIXME: make the `Std` step return some type-level "proof" that std was indeed built,
|
||||
// and then require passing that to all Cargo invocations that we do.
|
||||
|
||||
// The "stage 0" std is always precompiled and comes with the stage0 compiler, so we have
|
||||
// special logic for it, to avoid creating needless and confusing Std steps that don't
|
||||
// actually build anything.
|
||||
if compiler.stage == 0 {
|
||||
if target != compiler.host {
|
||||
panic!(
|
||||
r"It is not possible to build the standard library for `{target}` using the stage0 compiler.
|
||||
You have to build a stage1 compiler for `{}` first, and then use it to build a standard library for `{target}`.
|
||||
",
|
||||
compiler.host
|
||||
)
|
||||
}
|
||||
|
||||
// We still need to link the prebuilt standard library into the ephemeral stage0 sysroot
|
||||
self.ensure(StdLink::from_std(Std::new(compiler, target), compiler));
|
||||
} else {
|
||||
// This step both compiles the std and links it into the compiler's sysroot.
|
||||
// Yes, it's quite magical and side-effecty.. would be nice to refactor later.
|
||||
self.ensure(Std::new(compiler, target));
|
||||
}
|
||||
}
|
||||
|
||||
pub fn sysroot(&self, compiler: Compiler) -> PathBuf {
|
||||
self.ensure(compile::Sysroot::new(compiler))
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue