Skip to content

Support profile overrides for -Z build-std #15811

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

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 13 additions & 20 deletions src/cargo/core/profiles.rs
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Similar to #15772 (comment) and #15670 (comment), build-std's design is in flux. We might want to hold off on making design changes at this momemnt. Also, we generally prefer to have a design discussed and approved before proceeding to implementation.

See also rust-lang/wg-cargo-std-aware#2 for the relevant build-std profile overrides.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I did not believe a design was required because I was not adding any new features, just fixing a bug (that when an override is set for core, and core is being built, we don't use the override).

Those overrides don't allow you to set core to be built with debug-assertions disabled while building the rest of the world with debug-assertions enabled, so they don't address the issue. Should I file a bug instead? This is preventing me from enabling BTI and PAC for a firmware project.

Original file line number Diff line number Diff line change
Expand Up @@ -25,9 +25,7 @@ use crate::core::Feature;
use crate::core::compiler::{CompileKind, CompileTarget, Unit};
use crate::core::dependency::Artifact;
use crate::core::resolver::features::FeaturesFor;
use crate::core::{
PackageId, PackageIdSpec, PackageIdSpecQuery, Resolve, Shell, Target, Workspace,
};
use crate::core::{PackageId, PackageIdSpec, PackageIdSpecQuery, Shell, Target, Workspace};
use crate::util::interning::InternedString;
use crate::util::toml::validate_profile;
use crate::util::{CargoResult, GlobalContext, closest_msg, context};
Expand Down Expand Up @@ -352,11 +350,11 @@ impl Profiles {
}

/// Used to check for overrides for non-existing packages.
pub fn validate_packages(
pub fn validate_packages<I: Iterator<Item = PackageId>>(
&self,
profiles: Option<&TomlProfiles>,
shell: &mut Shell,
resolve: &Resolve,
packages: impl Fn() -> I,
) -> CargoResult<()> {
for (name, profile) in &self.by_name {
// If the user did not specify an override, skip this. This is here
Expand All @@ -372,13 +370,13 @@ impl Profiles {
{
continue;
}
let found = validate_packages_unique(resolve, name, &profile.toml)?;
let found = validate_packages_unique(&packages, name, &profile.toml)?;
// We intentionally do not validate unmatched packages for config
// profiles, in case they are defined in a central location. This
// iterates over the manifest profiles only.
if let Some(profiles) = profiles {
if let Some(toml_profile) = profiles.get(name) {
validate_packages_unmatched(shell, resolve, name, toml_profile, &found)?;
validate_packages_unmatched(shell, &packages, name, toml_profile, &found)?;
}
}
}
Expand Down Expand Up @@ -1335,8 +1333,8 @@ fn get_config_profile(ws: &Workspace<'_>, name: &str) -> CargoResult<Option<Toml
///
/// For example `[profile.dev.package.bar]` and `[profile.dev.package."bar:0.5.0"]`
/// would both match `bar:0.5.0` which would be ambiguous.
fn validate_packages_unique(
resolve: &Resolve,
fn validate_packages_unique<I: Iterator<Item = PackageId>>(
packages: impl Fn() -> I,
name: &str,
toml: &Option<TomlProfile>,
) -> CargoResult<HashSet<PackageIdSpec>> {
Expand All @@ -1348,7 +1346,7 @@ fn validate_packages_unique(
};
// Verify that a package doesn't match multiple spec overrides.
let mut found = HashSet::new();
for pkg_id in resolve.iter() {
for pkg_id in packages() {
let matches: Vec<&PackageIdSpec> = overrides
.keys()
.filter_map(|key| match *key {
Expand Down Expand Up @@ -1389,9 +1387,9 @@ fn validate_packages_unique(
/// Check for any profile override specs that do not match any known packages.
///
/// This helps check for typos and mistakes.
fn validate_packages_unmatched(
fn validate_packages_unmatched<I: Iterator<Item = PackageId>>(
shell: &mut Shell,
resolve: &Resolve,
packages: impl Fn() -> I,
name: &str,
toml: &TomlProfile,
found: &HashSet<PackageIdSpec>,
Expand All @@ -1411,8 +1409,7 @@ fn validate_packages_unmatched(
});
for spec in missing_specs {
// See if there is an exact name match.
let name_matches: Vec<String> = resolve
.iter()
let name_matches: Vec<String> = packages()
.filter_map(|pkg_id| {
if pkg_id.name() == spec.name() {
Some(pkg_id.to_string())
Expand All @@ -1422,12 +1419,8 @@ fn validate_packages_unmatched(
})
.collect();
if name_matches.is_empty() {
let suggestion = closest_msg(
&spec.name(),
resolve.iter(),
|p| p.name().as_str(),
"package",
);
let suggestion =
closest_msg(&spec.name(), packages(), |p| p.name().as_str(), "package");
shell.warn(format!(
"profile package spec `{}` in profile `{}` did not match any packages{}",
spec, name, suggestion
Expand Down
13 changes: 8 additions & 5 deletions src/cargo/ops/cargo_compile/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -344,11 +344,14 @@ pub fn create_bcx<'a, 'gctx>(
}

let profiles = Profiles::new(ws, build_config.requested_profile)?;
profiles.validate_packages(
ws.profiles(),
&mut gctx.shell(),
workspace_resolve.as_ref().unwrap_or(&resolve),
)?;
let pkg_resolve = workspace_resolve.as_ref().unwrap_or(&resolve);
if let Some((std_resolve, _)) = &std_resolve_features {
profiles.validate_packages(ws.profiles(), &mut gctx.shell(), || {
pkg_resolve.iter().chain(std_resolve.iter())
})?
} else {
profiles.validate_packages(ws.profiles(), &mut gctx.shell(), || pkg_resolve.iter())?
};

// If `--target` has not been specified, then the unit graph is built
// assuming `--target $HOST` was specified. See
Expand Down
44 changes: 44 additions & 0 deletions tests/testsuite/standard_lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -866,3 +866,47 @@ fn fetch() {
.with_stderr_does_not_contain("[DOWNLOADED] [..]")
.run();
}

#[cargo_test(build_std_mock)]
fn core_profile() {
let setup = setup();

let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "profile-check"
edition = "2024"

[profile.dev.package.core]
debug-assertions = false
"#,
)
.file("src/lib.rs", "extern crate core;")
.build();
p.cargo("build -v")
.build_std_arg(&setup, "compiler_builtins,core")
.with_stderr_data(
str![[r#"
[UPDATING] `dummy-registry` index
[DOWNLOADING] crates ...
[DOWNLOADED] registry-dep-using-std v1.0.0 (registry `dummy-registry`)
[DOWNLOADED] registry-dep-using-core v1.0.0 (registry `dummy-registry`)
[DOWNLOADED] registry-dep-using-alloc v1.0.0 (registry `dummy-registry`)
[COMPILING] compiler_builtins v0.1.0 ([..]/library/compiler_builtins)
[COMPILING] core v0.1.0 ([..]/library/core)
[COMPILING] profile-check v0.0.0 ([ROOT]/foo)
[RUNNING] `[..] rustc --crate-name compiler_builtins [..]`
[RUNNING] `[..] rustc --crate-name core [..] -C debug-assertions=off [..]`
[RUNNING] `[..] rustc --crate-name profile_check [..]`
[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s

"#]]
.unordered(),
)
.with_stderr_does_not_contain(
"[RUNNING] `[..] rustc --crate-name compiler_builtins [..] -C debug-assertions=off [..]`",
)
.run();
}
Loading