diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:18:58 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-17 12:18:58 +0000 |
commit | a4b7ed7a42c716ab9f05e351f003d589124fd55d (patch) | |
tree | b620cd3f223850b28716e474e80c58059dca5dd4 /src/bootstrap/builder.rs | |
parent | Adding upstream version 1.67.1+dfsg1. (diff) | |
download | rustc-a4b7ed7a42c716ab9f05e351f003d589124fd55d.tar.xz rustc-a4b7ed7a42c716ab9f05e351f003d589124fd55d.zip |
Adding upstream version 1.68.2+dfsg1.upstream/1.68.2+dfsg1
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'src/bootstrap/builder.rs')
-rw-r--r-- | src/bootstrap/builder.rs | 218 |
1 files changed, 152 insertions, 66 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 8ee6d49da..b4fc1d4f2 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -13,17 +13,18 @@ use std::time::{Duration, Instant}; use crate::cache::{Cache, Interned, INTERNER}; use crate::config::{SplitDebuginfo, TargetSelection}; -use crate::dist; use crate::doc; use crate::flags::{Color, Subcommand}; use crate::install; use crate::native; use crate::run; +use crate::setup; use crate::test; use crate::tool::{self, SourceType}; use crate::util::{self, add_dylib_path, add_link_lib_path, exe, libdir, output, t}; use crate::EXTRA_CHECK_CFGS; use crate::{check, compile, Crate}; +use crate::{clean, dist}; use crate::{Build, CLang, DocTests, GitRepo, Mode}; pub use crate::Compiler; @@ -95,6 +96,35 @@ impl RunConfig<'_> { pub fn build_triple(&self) -> TargetSelection { self.builder.build.build } + + /// Return a list of crate names selected by `run.paths`. + pub fn cargo_crates_in_set(&self) -> Interned<Vec<String>> { + let mut crates = Vec::new(); + for krate in &self.paths { + let path = krate.assert_single_path(); + let crate_name = self.builder.crate_paths[&path.path]; + crates.push(crate_name.to_string()); + } + INTERNER.intern_list(crates) + } +} + +/// A description of the crates in this set, suitable for passing to `builder.info`. +/// +/// `crates` should be generated by [`RunConfig::cargo_crates_in_set`]. +pub fn crate_description(crates: &[impl AsRef<str>]) -> String { + if crates.is_empty() { + return "".into(); + } + + let mut descr = String::from(" {"); + descr.push_str(crates[0].as_ref()); + for krate in &crates[1..] { + descr.push_str(", "); + descr.push_str(krate.as_ref()); + } + descr.push('}'); + descr } struct StepDescription { @@ -161,9 +191,9 @@ pub enum PathSet { /// A "suite" of paths. /// /// These can match as a path suffix (like `Set`), or as a prefix. For - /// example, a command-line value of `src/test/ui/abi/variadic-ffi.rs` - /// will match `src/test/ui`. A command-line value of `ui` would also - /// match `src/test/ui`. + /// example, a command-line value of `tests/ui/abi/variadic-ffi.rs` + /// will match `tests/ui`. A command-line value of `ui` would also + /// match `tests/ui`. Suite(TaskPath), } @@ -433,8 +463,11 @@ impl<'a> ShouldRun<'a> { // single alias, which does not correspond to any on-disk path pub fn alias(mut self, alias: &str) -> Self { + // exceptional case for `Kind::Setup` because its `library` + // and `compiler` options would otherwise naively match with + // `compiler` and `library` folders respectively. assert!( - !self.builder.src.join(alias).exists(), + self.kind == Kind::Setup || !self.builder.src.join(alias).exists(), "use `builder.path()` for real paths: {}", alias ); @@ -629,6 +662,7 @@ impl<'a> Builder<'a> { crate::toolstate::ToolStateCheck, test::ExpandYamlAnchors, test::Tidy, + test::TidySelfTest, test::Ui, test::RunPassValgrind, test::MirOpt, @@ -698,6 +732,7 @@ impl<'a> Builder<'a> { doc::RustdocBook, doc::RustByExample, doc::RustcBook, + doc::Cargo, doc::CargoBook, doc::Clippy, doc::ClippyBook, @@ -744,6 +779,7 @@ impl<'a> Builder<'a> { install::RustDemangler, install::Clippy, install::Miri, + install::LlvmTools, install::Analysis, install::Src, install::Rustc @@ -757,8 +793,10 @@ impl<'a> Builder<'a> { run::CollectLicenseMetadata, run::GenerateCopyright, ), - // These commands either don't use paths, or they're special-cased in Build::build() - Kind::Clean | Kind::Format | Kind::Setup => vec![], + Kind::Setup => describe!(setup::Profile), + Kind::Clean => describe!(clean::CleanAll, clean::Rustc, clean::Std), + // special-cased in Build::build() + Kind::Format => vec![], } } @@ -820,10 +858,12 @@ impl<'a> Builder<'a> { Subcommand::Dist { ref paths } => (Kind::Dist, &paths[..]), Subcommand::Install { ref paths } => (Kind::Install, &paths[..]), Subcommand::Run { ref paths, .. } => (Kind::Run, &paths[..]), + Subcommand::Clean { ref paths, .. } => (Kind::Clean, &paths[..]), Subcommand::Format { .. } => (Kind::Format, &[][..]), - Subcommand::Clean { .. } | Subcommand::Setup { .. } => { - panic!() - } + Subcommand::Setup { profile: ref path } => ( + Kind::Setup, + path.as_ref().map_or([].as_slice(), |path| std::slice::from_ref(path)), + ), }; Self::new_internal(build, kind, paths.to_owned()) @@ -1058,7 +1098,7 @@ impl<'a> Builder<'a> { /// check build or dry-run, where there's no need to build all of LLVM. fn llvm_config(&self, target: TargetSelection) -> Option<PathBuf> { if self.config.llvm_enabled() && self.kind != Kind::Check && !self.config.dry_run() { - let llvm_config = self.ensure(native::Llvm { target }); + let native::LlvmResult { llvm_config, .. } = self.ensure(native::Llvm { target }); if llvm_config.is_file() { return Some(llvm_config); } @@ -1066,6 +1106,62 @@ impl<'a> Builder<'a> { None } + /// Like `cargo`, but only passes flags that are valid for all commands. + pub fn bare_cargo( + &self, + compiler: Compiler, + mode: Mode, + target: TargetSelection, + cmd: &str, + ) -> Command { + let mut cargo = Command::new(&self.initial_cargo); + // Run cargo from the source root so it can find .cargo/config. + // This matters when using vendoring and the working directory is outside the repository. + cargo.current_dir(&self.src); + + let out_dir = self.stage_out(compiler, mode); + cargo.env("CARGO_TARGET_DIR", &out_dir).arg(cmd); + + // Found with `rg "init_env_logger\("`. If anyone uses `init_env_logger` + // from out of tree it shouldn't matter, since x.py is only used for + // building in-tree. + let color_logs = ["RUSTDOC_LOG_COLOR", "RUSTC_LOG_COLOR", "RUST_LOG_COLOR"]; + match self.build.config.color { + Color::Always => { + cargo.arg("--color=always"); + for log in &color_logs { + cargo.env(log, "always"); + } + } + Color::Never => { + cargo.arg("--color=never"); + for log in &color_logs { + cargo.env(log, "never"); + } + } + Color::Auto => {} // nothing to do + } + + if cmd != "install" { + cargo.arg("--target").arg(target.rustc_target_arg()); + } else { + assert_eq!(target, compiler.host); + } + + if self.config.rust_optimize { + // FIXME: cargo bench/install do not accept `--release` + if cmd != "bench" && cmd != "install" { + cargo.arg("--release"); + } + } + + // Remove make-related flags to ensure Cargo can correctly set things up + cargo.env_remove("MAKEFLAGS"); + cargo.env_remove("MFLAGS"); + + cargo + } + /// Prepares an invocation of `cargo` to be run. /// /// This will create a `Command` that represents a pending execution of @@ -1081,11 +1177,8 @@ impl<'a> Builder<'a> { target: TargetSelection, cmd: &str, ) -> Cargo { - let mut cargo = Command::new(&self.initial_cargo); + let mut cargo = self.bare_cargo(compiler, mode, target, cmd); let out_dir = self.stage_out(compiler, mode); - // Run cargo from the source root so it can find .cargo/config. - // This matters when using vendoring and the working directory is outside the repository. - cargo.current_dir(&self.src); // Codegen backends are not yet tracked by -Zbinary-dep-depinfo, // so we need to explicitly clear out if they've been updated. @@ -1110,8 +1203,6 @@ impl<'a> Builder<'a> { self.clear_if_dirty(&my_out, &rustdoc); } - cargo.env("CARGO_TARGET_DIR", &out_dir).arg(cmd); - let profile_var = |name: &str| { let profile = if self.config.rust_optimize { "RELEASE" } else { "DEV" }; format!("CARGO_PROFILE_{}_{}", profile, name) @@ -1124,32 +1215,6 @@ impl<'a> Builder<'a> { cargo.env("REAL_LIBRARY_PATH", e); } - // Found with `rg "init_env_logger\("`. If anyone uses `init_env_logger` - // from out of tree it shouldn't matter, since x.py is only used for - // building in-tree. - let color_logs = ["RUSTDOC_LOG_COLOR", "RUSTC_LOG_COLOR", "RUST_LOG_COLOR"]; - match self.build.config.color { - Color::Always => { - cargo.arg("--color=always"); - for log in &color_logs { - cargo.env(log, "always"); - } - } - Color::Never => { - cargo.arg("--color=never"); - for log in &color_logs { - cargo.env(log, "never"); - } - } - Color::Auto => {} // nothing to do - } - - if cmd != "install" { - cargo.arg("--target").arg(target.rustc_target_arg()); - } else { - assert_eq!(target, compiler.host); - } - // Set a flag for `check`/`clippy`/`fix`, so that certain build // scripts can do less work (i.e. not building/requiring LLVM). if cmd == "check" || cmd == "clippy" || cmd == "fix" { @@ -1316,23 +1381,31 @@ impl<'a> Builder<'a> { // this), as well as #63012 which is the tracking issue for this // feature on the rustc side. cargo.arg("-Zbinary-dep-depinfo"); - match mode { - Mode::ToolBootstrap => { - // Restrict the allowed features to those passed by rustbuild, so we don't depend on nightly accidentally. - rustflags.arg("-Zallow-features=binary-dep-depinfo"); + let allow_features = match mode { + Mode::ToolBootstrap | Mode::ToolStd => { + // Restrict the allowed features so we don't depend on nightly + // accidentally. + // + // binary-dep-depinfo is used by rustbuild itself for all + // compilations. + // + // Lots of tools depend on proc_macro2 and proc-macro-error. + // Those have build scripts which assume nightly features are + // available if the `rustc` version is "nighty" or "dev". See + // bin/rustc.rs for why that is a problem. Instead of labeling + // those features for each individual tool that needs them, + // just blanket allow them here. + // + // If this is ever removed, be sure to add something else in + // its place to keep the restrictions in place (or make a way + // to unset RUSTC_BOOTSTRAP). + "binary-dep-depinfo,proc_macro_span,proc_macro_span_shrink,proc_macro_diagnostic" + .to_string() } - Mode::ToolStd => { - // Right now this is just compiletest and a few other tools that build on stable. - // Allow them to use `feature(test)`, but nothing else. - rustflags.arg("-Zallow-features=binary-dep-depinfo,test,proc_macro_internals,proc_macro_diagnostic,proc_macro_span"); - } - Mode::Std | Mode::Rustc | Mode::Codegen | Mode::ToolRustc => {} - } + Mode::Std | Mode::Rustc | Mode::Codegen | Mode::ToolRustc => String::new(), + }; cargo.arg("-j").arg(self.jobs().to_string()); - // Remove make-related flags to ensure Cargo can correctly set things up - cargo.env_remove("MAKEFLAGS"); - cargo.env_remove("MFLAGS"); // FIXME: Temporary fix for https://github.com/rust-lang/cargo/issues/3005 // Force cargo to output binaries with disambiguating hashes in the name @@ -1816,13 +1889,6 @@ impl<'a> Builder<'a> { } } - if self.config.rust_optimize { - // FIXME: cargo bench/install do not accept `--release` - if cmd != "bench" && cmd != "install" { - cargo.arg("--release"); - } - } - if self.config.locked_deps { cargo.arg("--locked"); } @@ -1853,11 +1919,14 @@ impl<'a> Builder<'a> { }; if let Some(limit) = limit { - rustflags.arg(&format!("-Cllvm-args=-import-instr-limit={}", limit)); + if stage == 0 || self.config.default_codegen_backend().unwrap_or_default() == "llvm" + { + rustflags.arg(&format!("-Cllvm-args=-import-instr-limit={}", limit)); + } } } - Cargo { command: cargo, rustflags, rustdocflags } + Cargo { command: cargo, rustflags, rustdocflags, allow_features } } /// Ensure that a given step is built, returning its output. This will @@ -2036,6 +2105,7 @@ pub struct Cargo { command: Command, rustflags: Rustflags, rustdocflags: Rustflags, + allow_features: String, } impl Cargo { @@ -2080,6 +2150,18 @@ impl Cargo { self.command.current_dir(dir); self } + + /// Adds nightly-only features that this invocation is allowed to use. + /// + /// By default, all nightly features are allowed. Once this is called, it + /// will be restricted to the given set. + pub fn allow_features(&mut self, features: &str) -> &mut Cargo { + if !self.allow_features.is_empty() { + self.allow_features.push(','); + } + self.allow_features.push_str(features); + self + } } impl From<Cargo> for Command { @@ -2094,6 +2176,10 @@ impl From<Cargo> for Command { cargo.command.env("RUSTDOCFLAGS", rustdocflags); } + if !cargo.allow_features.is_empty() { + cargo.command.env("RUSTC_ALLOW_FEATURES", cargo.allow_features); + } + cargo.command } } |