diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs index cf32d558d4a51..4d20ed841d47c 100644 --- a/compiler/rustc_codegen_ssa/src/back/link.rs +++ b/compiler/rustc_codegen_ssa/src/back/link.rs @@ -987,7 +987,7 @@ fn link_natively<'a, B: ArchiveBuilder<'a>>( // On MSVC packed debug information is produced by the linker itself so // there's no need to do anything else here. - SplitDebuginfo::Packed if sess.target.is_like_msvc => {} + SplitDebuginfo::Packed if sess.target.is_like_windows => {} // ... and otherwise we're processing a `*.dwp` packed dwarf file. // diff --git a/config.toml.example b/config.toml.example index 6e53d9b442f16..dd886879b145d 100644 --- a/config.toml.example +++ b/config.toml.example @@ -473,13 +473,23 @@ changelog-seen = 2 # FIXME(#61117): Some tests fail when this option is enabled. #debuginfo-level-tests = 0 -# Whether to run `dsymutil` on Apple platforms to gather debug info into .dSYM -# bundles. `dsymutil` adds time to builds for no clear benefit, and also makes -# it more difficult for debuggers to find debug info. The compiler currently -# defaults to running `dsymutil` to preserve its historical default, but when -# compiling the compiler itself, we skip it by default since we know it's safe -# to do so in that case. -#run-dsymutil = false +# Should rustc be build with split debuginfo? Default is platform dependent. +# Valid values are the same as those accepted by `-C split-debuginfo` +# (`off`/`unpacked`/`packed`). +# +# On Linux, split debuginfo is disabled by default. +# +# On Apple platforms, unpacked split debuginfo is used by default. Unpacked +# debuginfo does not run `dsymutil`, which packages debuginfo from disparate +# object files into a single `.dSYM` file. `dsymutil` adds time to builds for +# no clear benefit, and also makes it more difficult for debuggers to find +# debug info. The compiler currently defaults to running `dsymutil` to preserve +# its historical default, but when compiling the compiler itself, we skip it by +# default since we know it's safe to do so in that case. +# +# On Windows platforms, packed debuginfo is the only supported option, +# producing a `.pdb` file. +#split-debuginfo = if linux { off } else if windows { packed } else if apple { unpacked } # Whether or not `panic!`s generate backtraces (RUST_BACKTRACE) #backtrace = true diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 0276d15a5b472..8c68f14072772 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -14,7 +14,7 @@ use std::time::{Duration, Instant}; use crate::cache::{Cache, Interned, INTERNER}; use crate::check; use crate::compile; -use crate::config::TargetSelection; +use crate::config::{SplitDebuginfo, TargetSelection}; use crate::dist; use crate::doc; use crate::flags::{Color, Subcommand}; @@ -1365,17 +1365,17 @@ impl<'a> Builder<'a> { }, ); - // `dsymutil` adds time to builds on Apple platforms for no clear benefit, and also makes - // it more difficult for debuggers to find debug info. The compiler currently defaults to - // running `dsymutil` to preserve its historical default, but when compiling the compiler - // itself, we skip it by default since we know it's safe to do so in that case. - // See https://github.com/rust-lang/rust/issues/79361 for more info on this flag. - if target.contains("apple") { - if self.config.rust_run_dsymutil { - rustflags.arg("-Csplit-debuginfo=packed"); - } else { - rustflags.arg("-Csplit-debuginfo=unpacked"); + // FIXME(davidtwco): #[cfg(not(bootstrap))] - #95612 needs to be in the bootstrap compiler + // for this conditional to be removed. + if !target.contains("windows") || compiler.stage >= 1 { + if target.contains("linux") || target.contains("windows") { + rustflags.arg("-Zunstable-options"); } + match self.config.rust_split_debuginfo { + SplitDebuginfo::Packed => rustflags.arg("-Csplit-debuginfo=packed"), + SplitDebuginfo::Unpacked => rustflags.arg("-Csplit-debuginfo=unpacked"), + SplitDebuginfo::Off => rustflags.arg("-Csplit-debuginfo=off"), + }; } if self.config.cmd.bless() { diff --git a/src/bootstrap/config.rs b/src/bootstrap/config.rs index d7c29f6900a53..f273fb42215e9 100644 --- a/src/bootstrap/config.rs +++ b/src/bootstrap/config.rs @@ -130,7 +130,7 @@ pub struct Config { pub rust_debuginfo_level_std: u32, pub rust_debuginfo_level_tools: u32, pub rust_debuginfo_level_tests: u32, - pub rust_run_dsymutil: bool, + pub rust_split_debuginfo: SplitDebuginfo, pub rust_rpath: bool, pub rustc_parallel: bool, pub rustc_default_linker: Option, @@ -221,6 +221,46 @@ impl FromStr for LlvmLibunwind { } } +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] +pub enum SplitDebuginfo { + Packed, + Unpacked, + Off, +} + +impl Default for SplitDebuginfo { + fn default() -> Self { + SplitDebuginfo::Off + } +} + +impl std::str::FromStr for SplitDebuginfo { + type Err = (); + + fn from_str(s: &str) -> Result { + match s { + "packed" => Ok(SplitDebuginfo::Packed), + "unpacked" => Ok(SplitDebuginfo::Unpacked), + "off" => Ok(SplitDebuginfo::Off), + _ => Err(()), + } + } +} + +impl SplitDebuginfo { + /// Returns the default `-Csplit-debuginfo` value for the current target. See the comment for + /// `rust.split-debuginfo` in `config.toml.example`. + fn default_for_platform(target: &str) -> Self { + if target.contains("apple") { + SplitDebuginfo::Unpacked + } else if target.contains("windows") { + SplitDebuginfo::Packed + } else { + SplitDebuginfo::Off + } + } +} + #[derive(Copy, Clone, Default, PartialEq, Eq, PartialOrd, Ord, Hash)] pub struct TargetSelection { pub triple: Interned, @@ -586,6 +626,7 @@ define_config! { debuginfo_level_std: Option = "debuginfo-level-std", debuginfo_level_tools: Option = "debuginfo-level-tools", debuginfo_level_tests: Option = "debuginfo-level-tests", + split_debuginfo: Option = "split-debuginfo", run_dsymutil: Option = "run-dsymutil", backtrace: Option = "backtrace", incremental: Option = "incremental", @@ -992,7 +1033,12 @@ impl Config { debuginfo_level_std = rust.debuginfo_level_std; debuginfo_level_tools = rust.debuginfo_level_tools; debuginfo_level_tests = rust.debuginfo_level_tests; - config.rust_run_dsymutil = rust.run_dsymutil.unwrap_or(false); + config.rust_split_debuginfo = rust + .split_debuginfo + .as_deref() + .map(SplitDebuginfo::from_str) + .map(|v| v.expect("invalid value for rust.split_debuginfo")) + .unwrap_or(SplitDebuginfo::default_for_platform(&config.build.triple)); optimize = rust.optimize; ignore_git = rust.ignore_git; config.rust_new_symbol_mangling = rust.new_symbol_mangling;