diff --git a/crates/cargo-util-schemas/src/manifest/mod.rs b/crates/cargo-util-schemas/src/manifest/mod.rs index 563b7d329c7..beda04ecd89 100644 --- a/crates/cargo-util-schemas/src/manifest/mod.rs +++ b/crates/cargo-util-schemas/src/manifest/mod.rs @@ -899,6 +899,7 @@ pub struct TomlProfile { pub dir_name: Option, pub inherits: Option, pub strip: Option, + pub force_frame_pointers: Option, // Note that `rustflags` is used for the cargo-feature `profile_rustflags` pub rustflags: Option>, // These two fields must be last because they are sub-tables, and TOML @@ -995,6 +996,10 @@ impl TomlProfile { self.strip = Some(v.clone()); } + if let Some(v) = &profile.force_frame_pointers { + self.force_frame_pointers = Some(v.clone()); + } + if let Some(v) = &profile.trim_paths { self.trim_paths = Some(v.clone()) } diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 2a0fd8b40f3..65be618ba9d 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -1106,6 +1106,7 @@ fn build_base_args( ref panic, incremental, strip, + force_frame_pointers, rustflags: profile_rustflags, trim_paths, .. @@ -1285,6 +1286,10 @@ fn build_base_args( cmd.arg("-C").arg(format!("strip={}", strip)); } + if force_frame_pointers { + cmd.arg("-C").arg("force-frame-pointers=on"); + } + if unit.is_std { // -Zforce-unstable-if-unmarked prevents the accidental use of // unstable crates within the sysroot (such as "extern crate libc" or diff --git a/src/cargo/core/profiles.rs b/src/cargo/core/profiles.rs index 86d64d668d8..077f6d19281 100644 --- a/src/cargo/core/profiles.rs +++ b/src/cargo/core/profiles.rs @@ -331,6 +331,7 @@ impl Profiles { result.debuginfo = for_unit_profile.debuginfo; result.opt_level = for_unit_profile.opt_level; result.trim_paths = for_unit_profile.trim_paths.clone(); + result.force_frame_pointers = for_unit_profile.force_frame_pointers; result } @@ -574,6 +575,9 @@ fn merge_profile(profile: &mut Profile, toml: &TomlProfile) { if let Some(flags) = &toml.rustflags { profile.rustflags = flags.iter().map(InternedString::from).collect(); } + if let Some(force_frame_pointers) = toml.force_frame_pointers { + profile.force_frame_pointers = force_frame_pointers; + } if let Some(trim_paths) = &toml.trim_paths { profile.trim_paths = Some(trim_paths.clone()); } @@ -624,6 +628,7 @@ pub struct Profile { pub incremental: bool, pub panic: PanicStrategy, pub strip: Strip, + pub force_frame_pointers: bool, #[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, @@ -649,6 +654,7 @@ impl Default for Profile { incremental: false, panic: PanicStrategy::Unwind, strip: Strip::Deferred(StripInner::None), + force_frame_pointers: false, rustflags: vec![], trim_paths: None, } @@ -678,6 +684,7 @@ compact_debug! { incremental panic strip + force_frame_pointers rustflags trim_paths )] @@ -746,7 +753,12 @@ impl Profile { self.debug_assertions, self.overflow_checks, self.rpath, - (self.incremental, self.panic, self.strip), + ( + self.incremental, + self.panic, + self.strip, + self.force_frame_pointers, + ), &self.rustflags, &self.trim_paths, ) diff --git a/tests/testsuite/config.rs b/tests/testsuite/config.rs index 80be8dabc1c..36b393d0828 100644 --- a/tests/testsuite/config.rs +++ b/tests/testsuite/config.rs @@ -1662,6 +1662,7 @@ fn all_profile_options() { dir_name: Some(String::from("dir_name")), inherits: Some(String::from("debug")), strip: Some(cargo_toml::StringOrBool::String("symbols".to_string())), + force_frame_pointers: Some(true), package: None, build_override: None, rustflags: None, diff --git a/tests/testsuite/profiles.rs b/tests/testsuite/profiles.rs index 36a70391050..50d2bbed143 100644 --- a/tests/testsuite/profiles.rs +++ b/tests/testsuite/profiles.rs @@ -704,6 +704,79 @@ fn do_not_strip_debuginfo_with_requested_debug() { .run(); } +#[cargo_test] +fn force_frame_pointers_on_works() { + let p = project() + .file( + "Cargo.toml", + r#" + [profile.dev] + force-frame-pointers = true + + [package] + name = "foo" + version = "0.0.1" + edition = "2015" + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + + p.cargo("build -v") + .with_stderr_data(str![[r#" +[COMPILING] foo v0.0.1 ([ROOT]/foo) +[RUNNING] `rustc --crate-name foo [..] -C force-frame-pointers=on [..]` +[FINISHED] `dev` profile [unoptimized + debuginfo] target(s) in [ELAPSED]s + +"#]]) + .run(); +} + +#[cargo_test] +fn force_frame_pointers_off_works() { + let p = project() + .file( + "Cargo.toml", + r#" + [profile.dev] + force-frame-pointers = false + + [package] + name = "foo" + version = "0.0.1" + edition = "2015" + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + + p.cargo("build -v") + .with_stdout_does_not_contain(str!["force-frame-pointers"]) + .with_stderr_does_not_contain(str!["force-frame-pointers"]) + .run(); +} + +#[cargo_test] +fn force_frame_pointers_unspecified_works() { + let p = project() + .file( + "Cargo.toml", + r#" + [package] + name = "foo" + version = "0.0.1" + edition = "2015" + "#, + ) + .file("src/main.rs", "fn main() {}") + .build(); + + p.cargo("build -v") + .with_stdout_does_not_contain(str!["force-frame-pointers"]) + .with_stderr_does_not_contain(str!["force-frame-pointers"]) + .run(); +} + #[cargo_test] fn rustflags_works() { let p = project() diff --git a/tests/testsuite/unit_graph.rs b/tests/testsuite/unit_graph.rs index cccc79f1295..b959065e3f9 100644 --- a/tests/testsuite/unit_graph.rs +++ b/tests/testsuite/unit_graph.rs @@ -75,6 +75,7 @@ fn simple() { "codegen_units": null, "debug_assertions": true, "debuginfo": 2, + "force_frame_pointers": false, "incremental": false, "lto": "false", "name": "dev", @@ -120,6 +121,7 @@ fn simple() { "codegen_units": null, "debug_assertions": true, "debuginfo": 2, + "force_frame_pointers": false, "incremental": false, "lto": "false", "name": "dev", @@ -158,6 +160,7 @@ fn simple() { "codegen_units": null, "debug_assertions": true, "debuginfo": 2, + "force_frame_pointers": false, "incremental": false, "lto": "false", "name": "dev", @@ -201,6 +204,7 @@ fn simple() { "codegen_units": null, "debug_assertions": true, "debuginfo": 2, + "force_frame_pointers": false, "incremental": false, "lto": "false", "name": "dev",