Skip to content

Commit

Permalink
Allow named debuginfo options in Cargo.toml
Browse files Browse the repository at this point in the history
Rustc supports these since rust-lang/rust#109808. It's technically
possible to set a named debuginfo level through `RUSTFLAGS`, but in
practice cargo always passes its own opinion of what the debuginfo level
is, so allow it to be configured through cargo too.
  • Loading branch information
jyn514 committed Apr 11, 2023
1 parent 0e474cf commit e353f2e
Show file tree
Hide file tree
Showing 8 changed files with 86 additions and 36 deletions.
6 changes: 5 additions & 1 deletion src/cargo/core/compiler/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -603,9 +603,13 @@ fn link_targets(cx: &mut Context<'_, '_>, unit: &Unit, fresh: bool) -> CargoResu
}

if json_messages {
let debuginfo = profile.debuginfo.to_option().map(|d| match d.parse() {
Ok(n) => machine_message::ArtifactDebuginfo::Int(n),
Err(_) => machine_message::ArtifactDebuginfo::Named(d.to_string()),
});
let art_profile = machine_message::ArtifactProfile {
opt_level: profile.opt_level.as_str(),
debuginfo: profile.debuginfo.to_option(),
debuginfo,
debug_assertions: profile.debug_assertions,
overflow_checks: profile.overflow_checks,
test: unit_mode.is_any_test(),
Expand Down
44 changes: 25 additions & 19 deletions src/cargo/core/profiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ use crate::core::dependency::Artifact;
use crate::core::resolver::features::FeaturesFor;
use crate::core::{PackageId, PackageIdSpec, Resolve, Shell, Target, Workspace};
use crate::util::interning::InternedString;
use crate::util::toml::{ProfilePackageSpec, StringOrBool, TomlProfile, TomlProfiles, U32OrBool};
use crate::util::toml::{
ProfilePackageSpec, StringOrBool, TomlProfile, TomlProfiles, U32OrBoolOrString,
};
use crate::util::{closest_msg, config, CargoResult, Config};
use anyhow::{bail, Context as _};
use std::collections::{BTreeMap, HashMap, HashSet};
Expand Down Expand Up @@ -276,15 +278,13 @@ impl Profiles {
// platform which has a stable `-Csplit-debuginfo` option for rustc,
// and it's typically much faster than running `dsymutil` on all builds
// in incremental cases.
if let Some(debug) = profile.debuginfo.to_option() {
if profile.split_debuginfo.is_none() && debug > 0 {
let target = match &kind {
CompileKind::Host => self.rustc_host.as_str(),
CompileKind::Target(target) => target.short_name(),
};
if target.contains("-apple-") {
profile.split_debuginfo = Some(InternedString::new("unpacked"));
}
if profile.debuginfo.is_turned_on() && profile.split_debuginfo.is_none() {
let target = match &kind {
CompileKind::Host => self.rustc_host.as_str(),
CompileKind::Target(target) => target.short_name(),
};
if target.contains("-apple-") {
profile.split_debuginfo = Some(InternedString::new("unpacked"));
}
}

Expand Down Expand Up @@ -529,9 +529,12 @@ fn merge_profile(profile: &mut Profile, toml: &TomlProfile) {
profile.codegen_units = toml.codegen_units;
}
match toml.debug {
Some(U32OrBool::U32(debug)) => profile.debuginfo = DebugInfo::Explicit(debug),
Some(U32OrBool::Bool(true)) => profile.debuginfo = DebugInfo::Explicit(2),
Some(U32OrBool::Bool(false)) => profile.debuginfo = DebugInfo::None,
Some(U32OrBoolOrString::U32(debug)) => {
profile.debuginfo = DebugInfo::Explicit(debug.to_string().into())
}
Some(U32OrBoolOrString::Bool(true)) => profile.debuginfo = DebugInfo::Explicit("2".into()),
Some(U32OrBoolOrString::Bool(false)) => profile.debuginfo = DebugInfo::None,
Some(U32OrBoolOrString::String(ref s)) => profile.debuginfo = DebugInfo::Explicit(s.into()),
None => {}
}
if let Some(debug_assertions) = toml.debug_assertions {
Expand Down Expand Up @@ -683,7 +686,7 @@ impl Profile {
Profile {
name: InternedString::new("dev"),
root: ProfileRoot::Debug,
debuginfo: DebugInfo::Explicit(2),
debuginfo: DebugInfo::Explicit("2".into()),
debug_assertions: true,
overflow_checks: true,
incremental: true,
Expand Down Expand Up @@ -743,7 +746,7 @@ pub enum DebugInfo {
/// No debuginfo level was set.
None,
/// A debuginfo level that is explicitly set, by a profile or a user.
Explicit(u32),
Explicit(InternedString),
/// For internal purposes: a deferred debuginfo level that can be optimized
/// away, but has this value otherwise.
///
Expand All @@ -753,22 +756,25 @@ pub enum DebugInfo {
/// faster to build (see [DebugInfo::weaken]).
///
/// In all other situations, this level value will be the one to use.
Deferred(u32),
Deferred(InternedString),
}

impl DebugInfo {
/// The main way to interact with this debuginfo level, turning it into an Option.
pub fn to_option(&self) -> Option<u32> {
pub fn to_option(self) -> Option<InternedString> {
match self {
DebugInfo::None => None,
DebugInfo::Explicit(v) | DebugInfo::Deferred(v) => Some(*v),
DebugInfo::Explicit(v) | DebugInfo::Deferred(v) => Some(v),
}
}

/// Returns true if the debuginfo level is high enough (at least 1). Helper
/// for a common operation on the usual `Option` representation.
pub(crate) fn is_turned_on(&self) -> bool {
self.to_option().unwrap_or(0) != 0
match self.to_option().as_deref() {
None | Some("0") | Some("none") => false,
Some(_) => true,
}
}

pub(crate) fn is_deferred(&self) -> bool {
Expand Down
10 changes: 9 additions & 1 deletion src/cargo/util/machine_message.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,12 +55,20 @@ impl<'a> Message for Artifact<'a> {
#[derive(Serialize)]
pub struct ArtifactProfile {
pub opt_level: &'static str,
pub debuginfo: Option<u32>,
pub debuginfo: Option<ArtifactDebuginfo>,
pub debug_assertions: bool,
pub overflow_checks: bool,
pub test: bool,
}

/// Internally this is just a string, but keep using 0/1/2 as integers for compatibility.
#[derive(Serialize)]
#[serde(untagged)]
pub enum ArtifactDebuginfo {
Int(u32),
Named(String),
}

#[derive(Serialize)]
pub struct BuildScript<'a> {
pub package_id: PackageId,
Expand Down
7 changes: 4 additions & 3 deletions src/cargo/util/toml/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -443,10 +443,11 @@ impl ser::Serialize for TomlOptLevel {
}

#[derive(Clone, Debug, Deserialize, Serialize, Eq, PartialEq)]
#[serde(untagged, expecting = "expected a boolean or an integer")]
pub enum U32OrBool {
#[serde(untagged, expecting = "expected a boolean, integer, or string")]
pub enum U32OrBoolOrString {
U32(u32),
Bool(bool),
String(String),
}

#[derive(Deserialize, Serialize, Clone, Debug, Default, Eq, PartialEq)]
Expand All @@ -456,7 +457,7 @@ pub struct TomlProfile {
pub lto: Option<StringOrBool>,
pub codegen_backend: Option<InternedString>,
pub codegen_units: Option<u32>,
pub debug: Option<U32OrBool>,
pub debug: Option<U32OrBoolOrString>,
pub split_debuginfo: Option<String>,
pub debug_assertions: Option<bool>,
pub rpath: Option<bool>,
Expand Down
33 changes: 32 additions & 1 deletion tests/testsuite/bad_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1313,14 +1313,45 @@ fn bad_debuginfo() {
.file("src/lib.rs", "")
.build();

p.cargo("check")
.with_status(101)
.with_stderr(
"\
[CHECKING] foo v0.0.0 ([CWD])
error: incorrect value `a` for codegen option `debuginfo` [..]
error: could not compile `foo` (lib) due to previous error
",
)
.run();
}

#[cargo_test]
fn bad_debuginfo2() {
let p = project()
.file(
"Cargo.toml",
r#"
[package]
name = "foo"
version = "0.0.0"
authors = []
[profile.dev]
debug = 3.6
"#,
)
.file("src/lib.rs", "")
.build();

p.cargo("check")
.with_status(101)
.with_stderr(
"\
error: failed to parse manifest at `[..]`
Caused by:
expected a boolean or an integer
expected a boolean, integer, or string
in `profile.dev.debug`
",
)
Expand Down
8 changes: 4 additions & 4 deletions tests/testsuite/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -401,7 +401,7 @@ lto = false
opt_level: Some(cargo_toml::TomlOptLevel("s".to_string())),
lto: Some(cargo_toml::StringOrBool::Bool(true)),
codegen_units: Some(5),
debug: Some(cargo_toml::U32OrBool::Bool(true)),
debug: Some(cargo_toml::U32OrBoolOrString::Bool(true)),
debug_assertions: Some(true),
rpath: Some(true),
panic: Some("abort".to_string()),
Expand Down Expand Up @@ -444,15 +444,15 @@ fn profile_env_var_prefix() {
.build();
let p: cargo_toml::TomlProfile = config.get("profile.dev").unwrap();
assert_eq!(p.debug_assertions, None);
assert_eq!(p.debug, Some(cargo_toml::U32OrBool::U32(1)));
assert_eq!(p.debug, Some(cargo_toml::U32OrBoolOrString::U32(1)));

let config = ConfigBuilder::new()
.env("CARGO_PROFILE_DEV_DEBUG_ASSERTIONS", "false")
.env("CARGO_PROFILE_DEV_DEBUG", "1")
.build();
let p: cargo_toml::TomlProfile = config.get("profile.dev").unwrap();
assert_eq!(p.debug_assertions, Some(false));
assert_eq!(p.debug, Some(cargo_toml::U32OrBool::U32(1)));
assert_eq!(p.debug, Some(cargo_toml::U32OrBoolOrString::U32(1)));
}

#[cargo_test]
Expand Down Expand Up @@ -1511,7 +1511,7 @@ fn all_profile_options() {
lto: Some(cargo_toml::StringOrBool::String("thin".to_string())),
codegen_backend: Some(InternedString::new("example")),
codegen_units: Some(123),
debug: Some(cargo_toml::U32OrBool::U32(1)),
debug: Some(cargo_toml::U32OrBoolOrString::U32(1)),
split_debuginfo: Some("packed".to_string()),
debug_assertions: Some(true),
rpath: Some(true),
Expand Down
6 changes: 3 additions & 3 deletions tests/testsuite/profile_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -436,7 +436,7 @@ fn named_config_profile() {
assert_eq!(p.name, "foo");
assert_eq!(p.codegen_units, Some(2)); // "foo" from config
assert_eq!(p.opt_level, "1"); // "middle" from manifest
assert_eq!(p.debuginfo.to_option(), Some(1)); // "bar" from config
assert_eq!(p.debuginfo.to_option(), Some("1".into())); // "bar" from config
assert_eq!(p.debug_assertions, true); // "dev" built-in (ignore build-override)
assert_eq!(p.overflow_checks, true); // "dev" built-in (ignore package override)

Expand All @@ -445,7 +445,7 @@ fn named_config_profile() {
assert_eq!(bo.name, "foo");
assert_eq!(bo.codegen_units, Some(6)); // "foo" build override from config
assert_eq!(bo.opt_level, "0"); // default to zero
assert_eq!(bo.debuginfo.to_option(), Some(1)); // SAME as normal
assert_eq!(bo.debuginfo.to_option(), Some("1".into())); // SAME as normal
assert_eq!(bo.debug_assertions, false); // "foo" build override from manifest
assert_eq!(bo.overflow_checks, true); // SAME as normal

Expand All @@ -454,7 +454,7 @@ fn named_config_profile() {
assert_eq!(po.name, "foo");
assert_eq!(po.codegen_units, Some(7)); // "foo" package override from config
assert_eq!(po.opt_level, "1"); // SAME as normal
assert_eq!(po.debuginfo.to_option(), Some(1)); // SAME as normal
assert_eq!(po.debuginfo.to_option(), Some("1".into())); // SAME as normal
assert_eq!(po.debug_assertions, true); // SAME as normal
assert_eq!(po.overflow_checks, false); // "middle" package override from manifest
}
Expand Down
8 changes: 4 additions & 4 deletions tests/testsuite/unit_graph.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ fn simple() {
"codegen_backend": null,
"codegen_units": null,
"debug_assertions": true,
"debuginfo": 2,
"debuginfo": "2",
"incremental": false,
"lto": "false",
"name": "dev",
Expand Down Expand Up @@ -117,7 +117,7 @@ fn simple() {
"codegen_backend": null,
"codegen_units": null,
"debug_assertions": true,
"debuginfo": 2,
"debuginfo": "2",
"incremental": false,
"lto": "false",
"name": "dev",
Expand Down Expand Up @@ -155,7 +155,7 @@ fn simple() {
"codegen_backend": null,
"codegen_units": null,
"debug_assertions": true,
"debuginfo": 2,
"debuginfo": "2",
"incremental": false,
"lto": "false",
"name": "dev",
Expand Down Expand Up @@ -198,7 +198,7 @@ fn simple() {
"codegen_backend": null,
"codegen_units": null,
"debug_assertions": true,
"debuginfo": 2,
"debuginfo": "2",
"incremental": false,
"lto": "false",
"name": "dev",
Expand Down

0 comments on commit e353f2e

Please sign in to comment.