From 02ed9e6895c6524afa23caa2ac1d2b48d1739e0a Mon Sep 17 00:00:00 2001 From: matt rice Date: Sat, 7 Sep 2019 07:50:36 -0700 Subject: [PATCH] add mechanism for forcing frame pointer. --- src/lib.rs | 31 +++++++++++++++++++++++++++++++ tests/test.rs | 32 +++++++++++++++++++++++++++++++- 2 files changed, 62 insertions(+), 1 deletion(-) diff --git a/src/lib.rs b/src/lib.rs index 3c78420..44ec005 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -105,6 +105,7 @@ pub struct Build { out_dir: Option, opt_level: Option, debug: Option, + force_frame_pointer: Option, env: Vec<(OsString, OsString)>, compiler: Option, archiver: Option, @@ -209,8 +210,17 @@ impl ToolFamily { } ToolFamily::Gnu | ToolFamily::Clang => { cmd.push_cc_arg("-g".into()); + } + } + } + + /// What the flag to force frame pointers. + fn add_force_frame_pointer(&self, cmd: &mut Tool) { + match *self { + ToolFamily::Gnu | ToolFamily::Clang => { cmd.push_cc_arg("-fno-omit-frame-pointer".into()); } + _ => (), } } @@ -286,6 +296,7 @@ impl Build { out_dir: None, opt_level: None, debug: None, + force_frame_pointer: None, env: Vec::new(), compiler: None, archiver: None, @@ -758,6 +769,17 @@ impl Build { self } + /// Configures whether the compiler will emit instructions to store + /// frame pointers during codegen. + /// + /// This option is automatically enabled when debug information is emitted. + /// Otherwise the target platform compiler's default will be used. + /// You can use this option to force a specific setting. + pub fn force_frame_pointer(&mut self, force: bool) -> &mut Build { + self.force_frame_pointer = Some(force); + self + } + /// Configures the output directory where all object files and static /// libraries will be located. /// @@ -1348,6 +1370,11 @@ impl Build { family.add_debug_flags(cmd); } + if self.get_force_frame_pointer() { + let family = cmd.family; + family.add_force_frame_pointer(cmd); + } + // Target flags match cmd.family { ToolFamily::Clang => { @@ -2227,6 +2254,10 @@ impl Build { }) } + fn get_force_frame_pointer(&self) -> bool { + self.force_frame_pointer.unwrap_or_else(|| self.get_debug()) + } + fn get_out_dir(&self) -> Result { match self.out_dir.clone() { Some(p) => Ok(p), diff --git a/tests/test.rs b/tests/test.rs index 778ee21..def11f0 100644 --- a/tests/test.rs +++ b/tests/test.rs @@ -39,10 +39,40 @@ fn gnu_opt_level_s() { } #[test] -fn gnu_debug() { +fn gnu_debug_fp_auto() { let test = Test::gnu(); test.gcc().debug(true).file("foo.c").compile("foo"); test.cmd(0).must_have("-g"); + test.cmd(0).must_have("-fno-omit-frame-pointer"); +} + +#[test] +fn gnu_debug_fp() { + let test = Test::gnu(); + test.gcc().debug(true).file("foo.c").compile("foo"); + test.cmd(0).must_have("-g"); + test.cmd(0).must_have("-fno-omit-frame-pointer"); +} + +#[test] +fn gnu_debug_nofp() { + let test = Test::gnu(); + test.gcc() + .debug(true) + .force_frame_pointer(false) + .file("foo.c") + .compile("foo"); + test.cmd(0).must_have("-g"); + test.cmd(0).must_not_have("-fno-omit-frame-pointer"); + + let test = Test::gnu(); + test.gcc() + .force_frame_pointer(false) + .debug(true) + .file("foo.c") + .compile("foo"); + test.cmd(0).must_have("-g"); + test.cmd(0).must_not_have("-fno-omit-frame-pointer"); } #[test]