Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 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
5 changes: 5 additions & 0 deletions src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -796,6 +796,7 @@ fn build_base_args(
let bcx = cx.bcx;
let Profile {
ref opt_level,
codegen_backend,
codegen_units,
debuginfo,
debug_assertions,
Expand Down Expand Up @@ -860,6 +861,10 @@ fn build_base_args(
}
}

if let Some(backend) = codegen_backend {
cmd.arg("-Z").arg(&format!("codegen-backend={}", backend));
}

if let Some(n) = codegen_units {
cmd.arg("-C").arg(&format!("codegen-units={}", n));
}
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 @@ -402,6 +402,9 @@ features! {

// Allow to specify per-package targets (compile kinds)
(unstable, per_package_target, "", "reference/unstable.html#per-package-target"),

// Allow to specify which codegen backend should be used.
(unstable, codegen_backend, "", "reference/unstable.html#codegen-backend"),
}

pub struct Feature {
Expand Down
8 changes: 8 additions & 0 deletions src/cargo/core/profiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -565,6 +565,9 @@ fn merge_profile(profile: &mut Profile, toml: &TomlProfile) {
Some(StringOrBool::String(ref n)) => profile.lto = Lto::Named(InternedString::new(n)),
None => {}
}
if toml.codegen_backend.is_some() {
profile.codegen_backend = toml.codegen_backend;
}
if toml.codegen_units.is_some() {
profile.codegen_units = toml.codegen_units;
}
Expand Down Expand Up @@ -626,6 +629,8 @@ pub struct Profile {
pub root: ProfileRoot,
pub lto: Lto,
// `None` means use rustc default.
pub codegen_backend: Option<InternedString>,
// `None` means use rustc default.
pub codegen_units: Option<u32>,
pub debuginfo: Option<u32>,
pub split_debuginfo: Option<InternedString>,
Expand All @@ -644,6 +649,7 @@ impl Default for Profile {
opt_level: InternedString::new("0"),
root: ProfileRoot::Debug,
lto: Lto::Bool(false),
codegen_backend: None,
codegen_units: None,
debuginfo: None,
debug_assertions: false,
Expand All @@ -670,6 +676,7 @@ compact_debug! {
opt_level
lto
root
codegen_backend
codegen_units
debuginfo
split_debuginfo
Expand Down Expand Up @@ -757,6 +764,7 @@ impl Profile {
(
self.opt_level,
self.lto,
self.codegen_backend,
self.codegen_units,
self.debuginfo,
self.split_debuginfo,
Expand Down
25 changes: 22 additions & 3 deletions src/cargo/util/toml/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@ pub enum U32OrBool {
pub struct TomlProfile {
pub opt_level: Option<TomlOptLevel>,
pub lto: Option<StringOrBool>,
pub codegen_backend: Option<InternedString>,
pub codegen_units: Option<u32>,
pub debug: Option<U32OrBool>,
pub split_debuginfo: Option<String>,
Expand Down Expand Up @@ -491,12 +492,12 @@ impl TomlProfile {
) -> CargoResult<()> {
if let Some(ref profile) = self.build_override {
features.require(Feature::profile_overrides())?;
profile.validate_override("build-override")?;
profile.validate_override("build-override", features)?;
}
if let Some(ref packages) = self.package {
features.require(Feature::profile_overrides())?;
for profile in packages.values() {
profile.validate_override("package")?;
profile.validate_override("package", features)?;
}
}

Expand Down Expand Up @@ -562,6 +563,17 @@ impl TomlProfile {
if self.strip.is_some() {
features.require(Feature::strip())?;
}

if let Some(codegen_backend) = &self.codegen_backend {
features.require(Feature::codegen_backend())?;
if codegen_backend.contains('.') {
bail!(
"`profile.{}.codegen-backend` is an external backend, but only builtin codegen \
backends are allowed."
);
}
}

Ok(())
}

Expand Down Expand Up @@ -642,7 +654,7 @@ impl TomlProfile {
Ok(())
}

fn validate_override(&self, which: &str) -> CargoResult<()> {
fn validate_override(&self, which: &str, features: &Features) -> CargoResult<()> {
if self.package.is_some() {
bail!("package-specific profiles cannot be nested");
}
Expand All @@ -658,6 +670,9 @@ impl TomlProfile {
if self.rpath.is_some() {
bail!("`rpath` may not be specified in a `{}` profile", which)
}
if self.codegen_backend.is_some() {
features.require(Feature::codegen_backend())?;
}
Ok(())
}

Expand All @@ -671,6 +686,10 @@ impl TomlProfile {
self.lto = Some(v.clone());
}

if let Some(v) = profile.codegen_backend {
self.codegen_backend = Some(v);
}

if let Some(v) = profile.codegen_units {
self.codegen_units = Some(v);
}
Expand Down
18 changes: 18 additions & 0 deletions src/doc/src/reference/unstable.md
Original file line number Diff line number Diff line change
Expand Up @@ -1406,3 +1406,21 @@ environment variables.
The `rust-version` field in `Cargo.toml` has been stabilized in the 1.56 release.
See the [rust-version field](manifest.html#the-rust-version-field) for more
information on using the `rust-version` field and the `--ignore-rust-version` option.

### codegen-backend

The `codegen-backend` feature makes it possible to select the codegen backend used by rustc using a
profile.

Example:

```toml
[package]
name = "foo"

[dependencies]
serde = "1.0.117"

[profile.dev.package.foo]
codegen-backend = "cranelift"
```
Loading