Skip to content

Commit fe05362

Browse files
authored
Support more of Cargo's debug levels with Build::debug_str (#1624)
1 parent 324a8ea commit fe05362

File tree

3 files changed

+105
-12
lines changed

3 files changed

+105
-12
lines changed

src/lib.rs

Lines changed: 41 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -405,7 +405,7 @@ pub struct Build {
405405
host: Option<Arc<str>>,
406406
out_dir: Option<Arc<Path>>,
407407
opt_level: Option<Arc<str>>,
408-
debug: Option<bool>,
408+
debug: Option<Arc<str>>,
409409
force_frame_pointer: Option<bool>,
410410
env: Vec<(Arc<OsStr>, Arc<OsStr>)>,
411411
compiler: Option<Arc<Path>>,
@@ -1180,7 +1180,23 @@ impl Build {
11801180
/// This option is automatically scraped from the `DEBUG` environment
11811181
/// variable by build scripts, so it's not required to call this function.
11821182
pub fn debug(&mut self, debug: bool) -> &mut Build {
1183-
self.debug = Some(debug);
1183+
self.debug = Some(debug.to_string().into());
1184+
self
1185+
}
1186+
1187+
/// Configures whether the compiler will emit debug information when
1188+
/// generating object files.
1189+
///
1190+
/// This should be one of the values accepted by Cargo's [`debug`][]
1191+
/// profile setting, which cc-rs will try to map to the appropriate C
1192+
/// compiler flag.
1193+
///
1194+
/// This option is automatically scraped from the `DEBUG` environment
1195+
/// variable by build scripts, so it's not required to call this function.
1196+
///
1197+
/// [debuginfo]: https://doc.rust-lang.org/cargo/reference/profiles.html#debug
1198+
pub fn debug_str(&mut self, debug: &str) -> &mut Build {
1199+
self.debug = Some(debug.into());
11841200
self
11851201
}
11861202

@@ -2161,7 +2177,11 @@ impl Build {
21612177
cmd.args.push("-G".into());
21622178
}
21632179
let family = cmd.family;
2164-
family.add_debug_flags(cmd, self.get_dwarf_version());
2180+
family.add_debug_flags(
2181+
cmd,
2182+
self.get_debug_str().as_deref().unwrap_or_default(),
2183+
self.get_dwarf_version(),
2184+
);
21652185
}
21662186

21672187
if self.get_force_frame_pointer() {
@@ -3707,8 +3727,25 @@ impl Build {
37073727
}
37083728
}
37093729

3730+
/// Returns true if *any* debug info is enabled.
3731+
///
3732+
/// [`get_debug_str`] provides more detail.
37103733
fn get_debug(&self) -> bool {
3711-
self.debug.unwrap_or_else(|| self.getenv_boolean("DEBUG"))
3734+
match self.get_debug_str() {
3735+
Err(_) => false,
3736+
Ok(d) => match &*d {
3737+
// From https://doc.rust-lang.org/cargo/reference/profiles.html#debug
3738+
"" | "0" | "false" | "none" => false,
3739+
_ => true,
3740+
},
3741+
}
3742+
}
3743+
3744+
fn get_debug_str(&self) -> Result<Cow<'_, str>, Error> {
3745+
match &self.debug {
3746+
Some(d) => Ok(Cow::Borrowed(d)),
3747+
None => self.getenv_unwrap_str("DEBUG").map(Cow::Owned),
3748+
}
37123749
}
37133750

37143751
fn get_shell_escaped_flags(&self) -> bool {

src/tool.rs

Lines changed: 35 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -509,17 +509,46 @@ pub enum ToolFamily {
509509

510510
impl ToolFamily {
511511
/// What the flag to request debug info for this family of tools look like
512-
pub(crate) fn add_debug_flags(&self, cmd: &mut Tool, dwarf_version: Option<u32>) {
512+
pub(crate) fn add_debug_flags(
513+
&self,
514+
cmd: &mut Tool,
515+
debug_opt: &str,
516+
dwarf_version: Option<u32>,
517+
) {
513518
match *self {
514519
ToolFamily::Msvc { .. } => {
515520
cmd.push_cc_arg("-Z7".into());
516521
}
517522
ToolFamily::Gnu | ToolFamily::Clang { .. } => {
518-
cmd.push_cc_arg(
519-
dwarf_version
520-
.map_or_else(|| "-g".into(), |v| format!("-gdwarf-{v}"))
521-
.into(),
522-
);
523+
match debug_opt {
524+
// From https://doc.rust-lang.org/cargo/reference/profiles.html#debug
525+
"" | "0" | "false" | "none" => {
526+
debug_assert!(
527+
false,
528+
"earlier check should have avoided calling add_debug_flags"
529+
);
530+
}
531+
532+
// line-directives-only is LLVM-specific; for GCC we have to treat it like "1"
533+
"line-directives-only" if cmd.is_like_clang() => {
534+
cmd.push_cc_arg("-gline-directives-only".into());
535+
}
536+
// Clang has -gline-tables-only, but it's an alias for -g1 anyway.
537+
// https://clang.llvm.org/docs/ClangCommandLineReference.html#cmdoption-clang-gline-tables-only
538+
"1" | "limited" | "line-tables-only" | "line-directives-only" => {
539+
cmd.push_cc_arg("-g1".into());
540+
}
541+
"2" | "true" | "full" => {
542+
cmd.push_cc_arg("-g".into());
543+
}
544+
_ => {
545+
// Err on the side of including too much info rather than too little.
546+
cmd.push_cc_arg("-g".into());
547+
}
548+
}
549+
if let Some(v) = dwarf_version {
550+
cmd.push_cc_arg(format!("-gdwarf-{v}").into());
551+
}
523552
}
524553
}
525554
}

tests/test.rs

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,42 @@ fn gnu_debug() {
6363
.debug(true)
6464
.file("foo.c")
6565
.compile("foo");
66-
test.cmd(0).must_have("-gdwarf-4");
66+
test.cmd(0)
67+
.must_have("-g")
68+
.must_not_have("-g1")
69+
.must_have("-gdwarf-4");
6770

6871
let test = Test::gnu();
6972
test.gcc()
7073
.target("x86_64-apple-darwin")
7174
.debug(true)
7275
.file("foo.c")
7376
.compile("foo");
74-
test.cmd(0).must_have("-gdwarf-2");
77+
test.cmd(0)
78+
.must_have("-g")
79+
.must_not_have("-g1")
80+
.must_have("-gdwarf-2");
81+
}
82+
83+
#[test]
84+
fn gnu_debug_limited() {
85+
let test = Test::gnu();
86+
test.gcc().debug_str("limited").file("foo.c").compile("foo");
87+
test.cmd(0).must_not_have("-g").must_have("-g1");
88+
}
89+
90+
#[test]
91+
fn gnu_debug_none() {
92+
let test = Test::gnu();
93+
test.gcc().debug_str("none").file("foo.c").compile("foo");
94+
test.cmd(0).must_not_have("-g").must_not_have("-g1");
95+
}
96+
97+
#[test]
98+
fn gnu_debug_unknown() {
99+
let test = Test::gnu();
100+
test.gcc().debug_str("99").file("foo.c").compile("foo");
101+
test.cmd(0).must_have("-g").must_not_have("-g1");
75102
}
76103

77104
#[test]

0 commit comments

Comments
 (0)