Skip to content
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

feat: support rustflags per profile #10217

Merged
merged 1 commit into from
Jan 10, 2022
Merged
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
9 changes: 7 additions & 2 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -448,7 +448,7 @@ fn link_targets(cx: &mut Context<'_, '_>, unit: &Unit, fresh: bool) -> CargoResu
let export_dir = cx.files().export_dir();
let package_id = unit.pkg.package_id();
let manifest_path = PathBuf::from(unit.pkg.manifest_path());
let profile = unit.profile;
let profile = unit.profile.clone();
let unit_mode = unit.mode;
let features = unit.features.iter().map(|s| s.to_string()).collect();
let json_messages = bcx.build_config.emit_json();
Expand Down Expand Up @@ -863,8 +863,9 @@ fn build_base_args(
ref panic,
incremental,
strip,
rustflags,
..
} = unit.profile;
} = unit.profile.clone();
let test = unit.mode.is_any_test();

cmd.arg("--crate-name").arg(&unit.target.crate_name());
Expand Down Expand Up @@ -914,6 +915,10 @@ fn build_base_args(
cmd.arg("-C").arg(&format!("opt-level={}", opt_level));
}

if !rustflags.is_empty() {
cmd.args(&rustflags);
}

if *panic != PanicStrategy::Unwind {
cmd.arg("-C").arg(format!("panic={}", panic));
}
Expand Down
3 changes: 3 additions & 0 deletions src/cargo/core/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,9 @@ features! {

// Allow specifying different binary name apart from the crate name
(unstable, different_binary_name, "", "reference/unstable.html#different-binary-name"),

// Allow specifying rustflags directly in a profile
(unstable, profile_rustflags, "", "reference/unstable.html#profile-rustflags-option"),
}

pub struct Feature {
Expand Down
12 changes: 10 additions & 2 deletions src/cargo/core/profiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,7 +500,7 @@ impl ProfileMaker {
is_member: bool,
unit_for: UnitFor,
) -> Profile {
let mut profile = self.default;
let mut profile = self.default.clone();

// First apply profile-specific settings, things like
// `[profile.release]`
Expand Down Expand Up @@ -626,6 +626,9 @@ fn merge_profile(profile: &mut Profile, toml: &TomlProfile) {
if let Some(incremental) = toml.incremental {
profile.incremental = incremental;
}
if let Some(flags) = &toml.rustflags {
profile.rustflags = flags.clone();
}
profile.strip = match toml.strip {
Some(StringOrBool::Bool(true)) => Strip::Named(InternedString::new("symbols")),
None | Some(StringOrBool::Bool(false)) => Strip::None,
Expand All @@ -647,7 +650,7 @@ pub enum ProfileRoot {

/// Profile settings used to determine which compiler flags to use for a
/// target.
#[derive(Clone, Copy, Eq, PartialOrd, Ord, serde::Serialize)]
#[derive(Clone, Eq, PartialOrd, Ord, serde::Serialize)]
pub struct Profile {
pub name: InternedString,
pub opt_level: InternedString,
Expand All @@ -666,6 +669,9 @@ pub struct Profile {
pub incremental: bool,
pub panic: PanicStrategy,
pub strip: Strip,
#[serde(skip_serializing_if = "Vec::is_empty")] // remove when `rustflags` is stablized
// Note that `rustflags` is used for the cargo-feature `profile_rustflags`
pub rustflags: Vec<InternedString>,
zhamlin marked this conversation as resolved.
Show resolved Hide resolved
}

impl Default for Profile {
Expand All @@ -685,6 +691,7 @@ impl Default for Profile {
incremental: false,
panic: PanicStrategy::Unwind,
strip: Strip::None,
rustflags: vec![],
}
}
}
Expand Down Expand Up @@ -712,6 +719,7 @@ compact_debug! {
incremental
panic
strip
rustflags
)]
}
}
Expand Down
2 changes: 1 addition & 1 deletion src/cargo/ops/cargo_compile.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1606,7 +1606,7 @@ fn traverse_and_share(
let new_unit = interner.intern(
&unit.pkg,
&unit.target,
unit.profile,
unit.profile.clone(),
new_kind,
unit.mode,
unit.features.clone(),
Expand Down
10 changes: 10 additions & 0 deletions src/cargo/util/toml/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -413,6 +413,8 @@ pub struct TomlProfile {
pub dir_name: Option<InternedString>,
pub inherits: Option<InternedString>,
pub strip: Option<StringOrBool>,
// Note that `rustflags` is used for the cargo-feature `profile_rustflags`
pub rustflags: Option<Vec<InternedString>>,
// These two fields must be last because they are sub-tables, and TOML
// requires all non-tables to be listed first.
pub package: Option<BTreeMap<ProfilePackageSpec, TomlProfile>>,
Expand Down Expand Up @@ -530,6 +532,10 @@ impl TomlProfile {
}
}

if self.rustflags.is_some() {
features.require(Feature::profile_rustflags())?;
}

if let Some(codegen_backend) = &self.codegen_backend {
features.require(Feature::codegen_backend())?;
if codegen_backend.contains(|c: char| !c.is_ascii_alphanumeric() && c != '_') {
Expand Down Expand Up @@ -691,6 +697,10 @@ impl TomlProfile {
self.incremental = Some(v);
}

if let Some(v) = &profile.rustflags {
self.rustflags = Some(v.clone());
}

if let Some(other_package) = &profile.package {
match &mut self.package {
Some(self_package) => {
Expand Down
19 changes: 19 additions & 0 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@ Each new feature described below should explain how to use it.
* [rustdoc-map](#rustdoc-map) — Provides mappings for documentation to link to external sites like [docs.rs](https://docs.rs/).
* `Cargo.toml` extensions
* [Profile `strip` option](#profile-strip-option) — Forces the removal of debug information and symbols from executables.
* [Profile `rustflags` option](#profile-rustflags-option) — Passed directly to rustc.
* [per-package-target](#per-package-target) — Sets the `--target` to use for each individual package.
* Information and metadata
* [Build-plan](#build-plan) — Emits JSON information on which commands will be run.
Expand Down Expand Up @@ -820,6 +821,24 @@ The following is a description of the JSON structure:
}
```

### Profile `rustflags` option
* Original Issue: [rust-lang/cargo#7878](https://github.com/rust-lang/cargo/issues/7878)
* Tracking Issue: [rust-lang/cargo#10271](https://github.com/rust-lang/cargo/issues/10271)

This feature provides a new option in the `[profile]` section to specify flags
that are passed directly to rustc.
This can be enabled like so:

```toml
cargo-features = ["profile-rustflags"]

[package]
# ...

[profile.release]
rustflags = [ "-C", "..." ]
```

### rustdoc-map
* Tracking Issue: [#8296](https://github.com/rust-lang/cargo/issues/8296)

Expand Down
1 change: 1 addition & 0 deletions tests/testsuite/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1484,6 +1484,7 @@ fn all_profile_options() {
strip: Some(toml::StringOrBool::String("symbols".to_string())),
package: None,
build_override: None,
rustflags: None,
};
let mut overrides = BTreeMap::new();
let key = toml::ProfilePackageSpec::Spec(PackageIdSpec::parse("foo").unwrap());
Expand Down
98 changes: 98 additions & 0 deletions tests/testsuite/profiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -595,3 +595,101 @@ fn strip_accepts_false_to_disable_strip() {
.with_stderr_does_not_contain("-C strip")
.run();
}

#[cargo_test]
fn rustflags_works() {
let p = project()
.file(
"Cargo.toml",
r#"
cargo-features = ["profile-rustflags"]

[profile.dev]
rustflags = ["-C", "link-dead-code=yes"]

[package]
name = "foo"
version = "0.0.1"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();

p.cargo("build -v")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[COMPILING] foo [..]
[RUNNING] `rustc --crate-name foo [..] -C link-dead-code=yes [..]
[FINISHED] [..]
",
)
.run();
}

#[cargo_test]
fn rustflags_works_with_env() {
let p = project()
.file(
"Cargo.toml",
r#"
cargo-features = ["profile-rustflags"]

[package]
name = "foo"
version = "0.0.1"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();

p.cargo("build -v")
.env("CARGO_PROFILE_DEV_RUSTFLAGS", "-C link-dead-code=yes")
.masquerade_as_nightly_cargo()
.with_stderr(
"\
[COMPILING] foo [..]
[RUNNING] `rustc --crate-name foo [..] -C link-dead-code=yes [..]
[FINISHED] [..]
",
)
.run();
}

#[cargo_test]
fn rustflags_requires_cargo_feature() {
let p = project()
.file(
"Cargo.toml",
r#"
[profile.dev]
rustflags = ["-C", "link-dead-code=yes"]

[package]
name = "foo"
version = "0.0.1"
"#,
)
.file("src/main.rs", "fn main() {}")
.build();

p.cargo("build -v")
.masquerade_as_nightly_cargo()
.with_status(101)
.with_stderr(
"\
[ERROR] failed to parse manifest at `[CWD]/Cargo.toml`

Caused by:
feature `profile-rustflags` is required

The package requires the Cargo feature called `profile-rustflags`, but that feature is \
not stabilized in this version of Cargo (1.[..]).
Consider adding `cargo-features = [\"profile-rustflags\"]` to the top of Cargo.toml \
(above the [package] table) to tell Cargo you are opting in to use this unstable feature.
See https://doc.rust-lang.org/nightly/cargo/reference/unstable.html#profile-rustflags-option \
for more information about the status of this feature.
",
)
.run();
}