diff --git a/src/bootstrap/src/core/build_steps/check.rs b/src/bootstrap/src/core/build_steps/check.rs index 7f7faf077d047..ba12e64c4a26f 100644 --- a/src/bootstrap/src/core/build_steps/check.rs +++ b/src/bootstrap/src/core/build_steps/check.rs @@ -228,7 +228,7 @@ impl Step for Rustc { self.override_build_kind.unwrap_or(builder.kind), ); - rustc_cargo(builder, &mut cargo, target, &compiler); + rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates); // For ./x.py clippy, don't run with --all-targets because // linting tests and benchmarks can produce very noisy results diff --git a/src/bootstrap/src/core/build_steps/clippy.rs b/src/bootstrap/src/core/build_steps/clippy.rs index a2bb03cd5ac81..a0992350722fe 100644 --- a/src/bootstrap/src/core/build_steps/clippy.rs +++ b/src/bootstrap/src/core/build_steps/clippy.rs @@ -197,7 +197,7 @@ impl Step for Rustc { Kind::Clippy, ); - rustc_cargo(builder, &mut cargo, target, &compiler); + rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates); // Explicitly pass -p for all compiler crates -- this will force cargo // to also lint the tests/benches/examples for these crates, rather diff --git a/src/bootstrap/src/core/build_steps/compile.rs b/src/bootstrap/src/core/build_steps/compile.rs index eef548033f1c6..662012a20d174 100644 --- a/src/bootstrap/src/core/build_steps/compile.rs +++ b/src/bootstrap/src/core/build_steps/compile.rs @@ -983,7 +983,7 @@ impl Step for Rustc { Kind::Build, ); - rustc_cargo(builder, &mut cargo, target, &compiler); + rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates); // NB: all RUSTFLAGS should be added to `rustc_cargo()` so they will be // consistently applied by check/doc/test modes too. @@ -1042,10 +1042,11 @@ pub fn rustc_cargo( cargo: &mut Cargo, target: TargetSelection, compiler: &Compiler, + crates: &[String], ) { cargo .arg("--features") - .arg(builder.rustc_features(builder.kind, target)) + .arg(builder.rustc_features(builder.kind, target, crates)) .arg("--manifest-path") .arg(builder.src.join("compiler/rustc/Cargo.toml")); diff --git a/src/bootstrap/src/core/build_steps/doc.rs b/src/bootstrap/src/core/build_steps/doc.rs index ffb617c642baf..f604cdbe27914 100644 --- a/src/bootstrap/src/core/build_steps/doc.rs +++ b/src/bootstrap/src/core/build_steps/doc.rs @@ -826,7 +826,7 @@ impl Step for Rustc { // see https://github.com/rust-lang/rust/pull/122066#issuecomment-1983049222 // cargo.rustdocflag("--generate-link-to-definition"); - compile::rustc_cargo(builder, &mut cargo, target, &compiler); + compile::rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates); cargo.arg("-Zskip-rustdoc-fingerprint"); // Only include compiler crates, no dependencies of those, such as `libc`. diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index a8e1254047363..3ef8c0ea4b2c9 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2690,7 +2690,7 @@ impl Step for Crate { } } Mode::Rustc => { - compile::rustc_cargo(builder, &mut cargo, target, &compiler); + compile::rustc_cargo(builder, &mut cargo, target, &compiler, &self.crates); } _ => panic!("can only test libraries"), }; diff --git a/src/bootstrap/src/core/metadata.rs b/src/bootstrap/src/core/metadata.rs index 1016607fc8318..d665544f59339 100644 --- a/src/bootstrap/src/core/metadata.rs +++ b/src/bootstrap/src/core/metadata.rs @@ -1,3 +1,4 @@ +use std::collections::BTreeMap; use std::path::PathBuf; use serde_derive::Deserialize; @@ -21,6 +22,7 @@ struct Package { manifest_path: String, dependencies: Vec, targets: Vec, + features: BTreeMap>, } /// For more information, see the output of @@ -51,7 +53,13 @@ pub fn build(build: &mut Build) { .map(|dep| dep.name) .collect(); let has_lib = package.targets.iter().any(|t| t.kind.iter().any(|k| k == "lib")); - let krate = Crate { name: name.clone(), deps, path, has_lib }; + let krate = Crate { + name: name.clone(), + deps, + path, + has_lib, + features: package.features.keys().cloned().collect(), + }; let relative_path = krate.local_path(build); build.crates.insert(name.clone(), krate); let existing_path = build.crate_paths.insert(relative_path, name); diff --git a/src/bootstrap/src/lib.rs b/src/bootstrap/src/lib.rs index 07befa983c51e..fc12b359e0a34 100644 --- a/src/bootstrap/src/lib.rs +++ b/src/bootstrap/src/lib.rs @@ -183,6 +183,7 @@ struct Crate { deps: HashSet, path: PathBuf, has_lib: bool, + features: Vec, } impl Crate { @@ -672,16 +673,24 @@ impl Build { } /// Gets the space-separated set of activated features for the compiler. - fn rustc_features(&self, kind: Kind, target: TargetSelection) -> String { + fn rustc_features(&self, kind: Kind, target: TargetSelection, crates: &[String]) -> String { + let possible_features_by_crates: HashSet<_> = crates + .iter() + .flat_map(|krate| &self.crates[krate].features) + .map(std::ops::Deref::deref) + .collect(); + let check = |feature: &str| -> bool { + crates.is_empty() || possible_features_by_crates.contains(feature) + }; let mut features = vec![]; - if self.config.jemalloc { + if self.config.jemalloc && check("jemalloc") { features.push("jemalloc"); } - if self.config.llvm_enabled(target) || kind == Kind::Check { + if (self.config.llvm_enabled(target) || kind == Kind::Check) && check("llvm") { features.push("llvm"); } // keep in sync with `bootstrap/compile.rs:rustc_cargo_env` - if self.config.rustc_parallel { + if self.config.rustc_parallel && check("rustc_use_parallel_compiler") { features.push("rustc_use_parallel_compiler"); } if self.config.rust_randomize_layout { @@ -693,7 +702,7 @@ impl Build { // which is everything (including debug/trace/etc.) // if its unset, if debug_assertions is on, then debug_logging will also be on // as well as tracing *ignoring* this feature when debug_assertions is on - if !self.config.rust_debug_logging { + if !self.config.rust_debug_logging && check("max_level_info") { features.push("max_level_info"); }