From 538d59a8db28161dff38a096093567ae96f7a65a Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 31 Jan 2021 16:45:38 +0100 Subject: [PATCH 1/6] Add a profile option to select the codegen backend This makes it possible to compile only specific crates with a certain codegen backend. --- src/cargo/core/compiler/mod.rs | 5 +++++ src/cargo/core/features.rs | 3 +++ src/cargo/core/profiles.rs | 8 ++++++++ src/cargo/util/toml/mod.rs | 19 ++++++++++++++++--- src/doc/src/reference/unstable.md | 18 ++++++++++++++++++ 5 files changed, 50 insertions(+), 3 deletions(-) diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 1687a5d2ace..7007d0dd8c2 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -796,6 +796,7 @@ fn build_base_args( let bcx = cx.bcx; let Profile { ref opt_level, + codegen_backend, codegen_units, debuginfo, debug_assertions, @@ -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)); } diff --git a/src/cargo/core/features.rs b/src/cargo/core/features.rs index e338a66acea..31fe062ca0d 100644 --- a/src/cargo/core/features.rs +++ b/src/cargo/core/features.rs @@ -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 { diff --git a/src/cargo/core/profiles.rs b/src/cargo/core/profiles.rs index 04ec2e6f9e1..ac167f17363 100644 --- a/src/cargo/core/profiles.rs +++ b/src/cargo/core/profiles.rs @@ -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; } @@ -626,6 +629,8 @@ pub struct Profile { pub root: ProfileRoot, pub lto: Lto, // `None` means use rustc default. + pub codegen_backend: Option, + // `None` means use rustc default. pub codegen_units: Option, pub debuginfo: Option, pub split_debuginfo: Option, @@ -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, @@ -670,6 +676,7 @@ compact_debug! { opt_level lto root + codegen_backend codegen_units debuginfo split_debuginfo @@ -757,6 +764,7 @@ impl Profile { ( self.opt_level, self.lto, + self.codegen_backend, self.codegen_units, self.debuginfo, self.split_debuginfo, diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index e32160ea2b3..485e562919d 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -433,6 +433,7 @@ pub enum U32OrBool { pub struct TomlProfile { pub opt_level: Option, pub lto: Option, + pub codegen_backend: Option, pub codegen_units: Option, pub debug: Option, pub split_debuginfo: Option, @@ -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)?; } } @@ -562,6 +563,11 @@ impl TomlProfile { if self.strip.is_some() { features.require(Feature::strip())?; } + + if self.codegen_backend.is_some() { + features.require(Feature::codegen_backend())?; + } + Ok(()) } @@ -642,7 +648,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"); } @@ -658,6 +664,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(()) } @@ -671,6 +680,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); } diff --git a/src/doc/src/reference/unstable.md b/src/doc/src/reference/unstable.md index 0eafbd0e5fe..6bdc2ac582e 100644 --- a/src/doc/src/reference/unstable.md +++ b/src/doc/src/reference/unstable.md @@ -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" +``` From 88da2395bdba2484f01492df511bcb7ef4ed7e98 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 31 Jan 2021 18:08:47 +0100 Subject: [PATCH 2/6] Update test --- tests/testsuite/unit_graph.rs | 242 +++++++++++++++++----------------- 1 file changed, 124 insertions(+), 118 deletions(-) diff --git a/tests/testsuite/unit_graph.rs b/tests/testsuite/unit_graph.rs index 977d04915c5..fa4b74dabaf 100644 --- a/tests/testsuite/unit_graph.rs +++ b/tests/testsuite/unit_graph.rs @@ -49,177 +49,183 @@ fn simple() { .masquerade_as_nightly_cargo() .with_json( r#"{ - "version": 1, + "roots": [ + 3 + ], "units": [ { + "dependencies": [ + { + "extern_crate_name": "b", + "index": 1, + "noprelude": false, + "public": false + } + ], + "features": [ + "feata" + ], + "mode": "build", "pkg_id": "a 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "platform": null, + "profile": { + "codegen_backend": null, + "codegen_units": null, + "debug_assertions": true, + "debuginfo": 2, + "incremental": false, + "lto": "false", + "name": "dev", + "opt_level": "0", + "overflow_checks": true, + "panic": "unwind", + "rpath": false, + "split_debuginfo": null, + "strip": "none" + }, "target": { - "kind": [ + "crate_types": [ "lib" ], - "crate_types": [ + "doc": true, + "doctest": true, + "edition": "2015", + "kind": [ "lib" ], "name": "a", "src_path": "[..]/a-1.0.0/src/lib.rs", - "edition": "2015", - "doc": true, - "doctest": true, "test": true - }, + } + }, + { + "dependencies": [ + { + "extern_crate_name": "c", + "index": 2, + "noprelude": false, + "public": false + } + ], + "features": [ + "featb" + ], + "mode": "build", + "pkg_id": "b 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "platform": null, "profile": { - "name": "dev", - "opt_level": "0", - "lto": "false", + "codegen_backend": null, "codegen_units": null, - "debuginfo": 2, "debug_assertions": true, - "overflow_checks": true, - "rpath": false, + "debuginfo": 2, "incremental": false, + "lto": "false", + "name": "dev", + "opt_level": "0", + "overflow_checks": true, "panic": "unwind", - "strip": "none", - "split_debuginfo": "{...}" + "rpath": false, + "split_debuginfo": null, + "strip": "none" }, - "platform": null, - "mode": "build", - "features": [ - "feata" - ], - "dependencies": [ - { - "index": 1, - "extern_crate_name": "b", - "public": false, - "noprelude": false - } - ] - }, - { - "pkg_id": "b 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "target": { - "kind": [ + "crate_types": [ "lib" ], - "crate_types": [ + "doc": true, + "doctest": true, + "edition": "2015", + "kind": [ "lib" ], "name": "b", "src_path": "[..]/b-1.0.0/src/lib.rs", - "edition": "2015", - "doc": true, - "doctest": true, "test": true - }, + } + }, + { + "dependencies": [], + "features": [ + "featc" + ], + "mode": "build", + "pkg_id": "c 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", + "platform": null, "profile": { - "name": "dev", - "opt_level": "0", - "lto": "false", + "codegen_backend": null, "codegen_units": null, - "debuginfo": 2, "debug_assertions": true, - "overflow_checks": true, - "rpath": false, + "debuginfo": 2, "incremental": false, + "lto": "false", + "name": "dev", + "opt_level": "0", + "overflow_checks": true, "panic": "unwind", - "strip": "none", - "split_debuginfo": "{...}" + "rpath": false, + "split_debuginfo": null, + "strip": "none" }, - "platform": null, - "mode": "build", - "features": [ - "featb" - ], - "dependencies": [ - { - "index": 2, - "extern_crate_name": "c", - "public": false, - "noprelude": false - } - ] - }, - { - "pkg_id": "c 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)", "target": { - "kind": [ + "crate_types": [ "lib" ], - "crate_types": [ + "doc": true, + "doctest": true, + "edition": "2015", + "kind": [ "lib" ], "name": "c", "src_path": "[..]/c-1.0.0/src/lib.rs", - "edition": "2015", - "test": true, - "doc": true, - "doctest": true - }, + "test": true + } + }, + { + "dependencies": [ + { + "extern_crate_name": "a", + "index": 0, + "noprelude": false, + "public": false + } + ], + "features": [], + "mode": "build", + "pkg_id": "foo 0.1.0 (path+file://[..]/foo)", + "platform": null, "profile": { - "name": "dev", - "opt_level": "0", - "lto": "false", + "codegen_backend": null, "codegen_units": null, - "debuginfo": 2, "debug_assertions": true, - "overflow_checks": true, - "rpath": false, + "debuginfo": 2, "incremental": false, + "lto": "false", + "name": "dev", + "opt_level": "0", + "overflow_checks": true, "panic": "unwind", - "strip": "none", - "split_debuginfo": "{...}" + "rpath": false, + "split_debuginfo": null, + "strip": "none" }, - "platform": null, - "mode": "build", - "features": [ - "featc" - ], - "dependencies": [] - }, - { - "pkg_id": "foo 0.1.0 (path+file://[..]/foo)", "target": { - "kind": [ + "crate_types": [ "lib" ], - "crate_types": [ + "doc": true, + "doctest": true, + "edition": "2015", + "kind": [ "lib" ], "name": "foo", "src_path": "[..]/foo/src/lib.rs", - "edition": "2015", - "test": true, - "doc": true, - "doctest": true - }, - "profile": { - "name": "dev", - "opt_level": "0", - "lto": "false", - "codegen_units": null, - "debuginfo": 2, - "debug_assertions": true, - "overflow_checks": true, - "rpath": false, - "incremental": false, - "panic": "unwind", - "strip": "none", - "split_debuginfo": "{...}" - }, - "platform": null, - "mode": "build", - "features": [], - "dependencies": [ - { - "index": 0, - "extern_crate_name": "a", - "public": false, - "noprelude": false - } - ] + "test": true + } } ], - "roots": [3] + "version": 1 } "#, ) From 2d73a9d544af46b3c47b9fb78f524a323bc2e58d Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 5 Aug 2021 15:26:01 +0200 Subject: [PATCH 3/6] Only allow internal backends --- src/cargo/util/toml/mod.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 485e562919d..618f5ff37aa 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -564,8 +564,14 @@ impl TomlProfile { features.require(Feature::strip())?; } - if self.codegen_backend.is_some() { + 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(()) From cd642e18937e66ca66e00905a44514c6eba7e6cc Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 5 Aug 2021 17:15:22 +0200 Subject: [PATCH 4/6] Update error message Co-authored-by: Josh Triplett --- src/cargo/util/toml/mod.rs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 618f5ff37aa..42851b9d4b6 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -566,10 +566,11 @@ impl TomlProfile { if let Some(codegen_backend) = &self.codegen_backend { features.require(Feature::codegen_backend())?; - if codegen_backend.contains('.') { + if codegen_backend.contains(|c| !c.is_ascii_alphanumeric() && c != '_') { bail!( - "`profile.{}.codegen-backend` is an external backend, but only builtin codegen \ - backends are allowed." + "`profile.{}.codegen-backend` setting of `{}` is not a valid backend name.", + name, + codegen_backend, ); } } From 1aa8fd57361a336579e2bf5d7b786cc53dcaed58 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Thu, 5 Aug 2021 17:17:50 +0200 Subject: [PATCH 5/6] Fix test --- tests/testsuite/unit_graph.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/testsuite/unit_graph.rs b/tests/testsuite/unit_graph.rs index fa4b74dabaf..b61cb453f14 100644 --- a/tests/testsuite/unit_graph.rs +++ b/tests/testsuite/unit_graph.rs @@ -80,7 +80,7 @@ fn simple() { "overflow_checks": true, "panic": "unwind", "rpath": false, - "split_debuginfo": null, + "split_debuginfo": "{...}", "strip": "none" }, "target": { @@ -125,7 +125,7 @@ fn simple() { "overflow_checks": true, "panic": "unwind", "rpath": false, - "split_debuginfo": null, + "split_debuginfo": "{...}", "strip": "none" }, "target": { @@ -163,7 +163,7 @@ fn simple() { "overflow_checks": true, "panic": "unwind", "rpath": false, - "split_debuginfo": null, + "split_debuginfo": "{...}", "strip": "none" }, "target": { @@ -206,7 +206,7 @@ fn simple() { "overflow_checks": true, "panic": "unwind", "rpath": false, - "split_debuginfo": null, + "split_debuginfo": "{...}", "strip": "none" }, "target": { From e96309abe04be841ade7adf4a32dbbd86e23207f Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 6 Aug 2021 20:10:26 +0200 Subject: [PATCH 6/6] Fix compile error --- src/cargo/util/toml/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 42851b9d4b6..7c472bf8b2f 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -566,7 +566,7 @@ impl TomlProfile { if let Some(codegen_backend) = &self.codegen_backend { features.require(Feature::codegen_backend())?; - if codegen_backend.contains(|c| !c.is_ascii_alphanumeric() && c != '_') { + if codegen_backend.contains(|c: char| !c.is_ascii_alphanumeric() && c != '_') { bail!( "`profile.{}.codegen-backend` setting of `{}` is not a valid backend name.", name,