1
Fork 0

Rollup merge of #79570 - alexcrichton:split-debuginfo, r=bjorn3

rustc: Stabilize `-Zrun-dsymutil` as `-Csplit-debuginfo`

This commit adds a new stable codegen option to rustc,
`-Csplit-debuginfo`. The old `-Zrun-dsymutil` flag is deleted and now
subsumed by this stable flag. Additionally `-Zsplit-dwarf` is also
subsumed by this flag but still requires `-Zunstable-options` to
actually activate. The `-Csplit-debuginfo` flag takes one of
three values:

* `off` - This indicates that split-debuginfo from the final artifact is
  not desired. This is not supported on Windows and is the default on
  Unix platforms except macOS. On macOS this means that `dsymutil` is
  not executed.

* `packed` - This means that debuginfo is desired in one location
  separate from the main executable. This is the default on Windows
  (`*.pdb`) and macOS (`*.dSYM`). On other Unix platforms this subsumes
  `-Zsplit-dwarf=single` and produces a `*.dwp` file.

* `unpacked` - This means that debuginfo will be roughly equivalent to
  object files, meaning that it's throughout the build directory
  rather than in one location (often the fastest for local development).
  This is not the default on any platform and is not supported on Windows.

Each target can indicate its own default preference for how debuginfo is
handled. Almost all platforms default to `off` except for Windows and
macOS which default to `packed` for historical reasons.

Some equivalencies for previous unstable flags with the new flags are:

* `-Zrun-dsymutil=yes` -> `-Csplit-debuginfo=packed`
* `-Zrun-dsymutil=no` -> `-Csplit-debuginfo=unpacked`
* `-Zsplit-dwarf=single` -> `-Csplit-debuginfo=packed`
* `-Zsplit-dwarf=split` -> `-Csplit-debuginfo=unpacked`

Note that `-Csplit-debuginfo` still requires `-Zunstable-options` for
non-macOS platforms since split-dwarf support was *just* implemented in
rustc.

There's some more rationale listed on #79361, but the main gist of the
motivation for this commit is that `dsymutil` can take quite a long time
to execute in debug builds and provides little benefit. This means that
incremental compile times appear that much worse on macOS because the
compiler is constantly running `dsymutil` over every single binary it
produces during `cargo build` (even build scripts!). Ideally rustc would
switch to not running `dsymutil` by default, but that's a problem left
to get tackled another day.

Closes #79361
This commit is contained in:
Yuki Okushi 2021-01-29 09:17:20 +09:00 committed by GitHub
commit d9e56f48c5
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
21 changed files with 352 additions and 134 deletions

View file

@ -1,6 +1,6 @@
use std::env;
use crate::spec::{LinkArgs, TargetOptions};
use crate::spec::{LinkArgs, SplitDebuginfo, TargetOptions};
pub fn opts(os: &str) -> TargetOptions {
// ELF TLS is only available in macOS 10.7+. If you try to compile for 10.6
@ -36,6 +36,10 @@ pub fn opts(os: &str) -> TargetOptions {
emit_debug_gdb_scripts: false,
eh_frame_header: false,
// The historical default for macOS targets is to run `dsymutil` which
// generates a packed version of debuginfo split from the main file.
split_debuginfo: SplitDebuginfo::Packed,
// This environment variable is pretty magical but is intended for
// producing deterministic builds. This was first discovered to be used
// by the `ar` tool as a way to control whether or not mtime entries in

View file

@ -448,6 +448,69 @@ impl fmt::Display for LinkOutputKind {
pub type LinkArgs = BTreeMap<LinkerFlavor, Vec<String>>;
#[derive(Clone, Copy, Hash, Debug, PartialEq, Eq)]
pub enum SplitDebuginfo {
/// Split debug-information is disabled, meaning that on supported platforms
/// you can find all debug information in the executable itself. This is
/// only supported for ELF effectively.
///
/// * Windows - not supported
/// * macOS - don't run `dsymutil`
/// * ELF - `.dwarf_*` sections
Off,
/// Split debug-information can be found in a "packed" location separate
/// from the final artifact. This is supported on all platforms.
///
/// * Windows - `*.pdb`
/// * macOS - `*.dSYM` (run `dsymutil`)
/// * ELF - `*.dwp` (run `rust-llvm-dwp`)
Packed,
/// Split debug-information can be found in individual object files on the
/// filesystem. The main executable may point to the object files.
///
/// * Windows - not supported
/// * macOS - supported, scattered object files
/// * ELF - supported, scattered `*.dwo` files
Unpacked,
}
impl SplitDebuginfo {
fn as_str(&self) -> &'static str {
match self {
SplitDebuginfo::Off => "off",
SplitDebuginfo::Packed => "packed",
SplitDebuginfo::Unpacked => "unpacked",
}
}
}
impl FromStr for SplitDebuginfo {
type Err = ();
fn from_str(s: &str) -> Result<SplitDebuginfo, ()> {
Ok(match s {
"off" => SplitDebuginfo::Off,
"unpacked" => SplitDebuginfo::Unpacked,
"packed" => SplitDebuginfo::Packed,
_ => return Err(()),
})
}
}
impl ToJson for SplitDebuginfo {
fn to_json(&self) -> Json {
self.as_str().to_json()
}
}
impl fmt::Display for SplitDebuginfo {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
f.write_str(self.as_str())
}
}
macro_rules! supported_targets {
( $(($( $triple:literal, )+ $module:ident ),)+ ) => {
$(mod $module;)+
@ -1085,6 +1148,10 @@ pub struct TargetOptions {
/// Is true if the target is an ARM architecture using thumb v1 which allows for
/// thumb and arm interworking.
pub has_thumb_interworking: bool,
/// How to handle split debug information, if at all. Specifying `None` has
/// target-specific meaning.
pub split_debuginfo: SplitDebuginfo,
}
impl Default for TargetOptions {
@ -1184,6 +1251,7 @@ impl Default for TargetOptions {
use_ctors_section: false,
eh_frame_header: true,
has_thumb_interworking: false,
split_debuginfo: SplitDebuginfo::Off,
}
}
}
@ -1382,6 +1450,18 @@ impl Target {
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, SplitDebuginfo) => ( {
let name = (stringify!($key_name)).replace("_", "-");
obj.find(&name[..]).and_then(|o| o.as_string().and_then(|s| {
match s.parse::<SplitDebuginfo>() {
Ok(level) => base.$key_name = level,
_ => return Some(Err(format!("'{}' is not a valid value for \
split-debuginfo. Use 'off' or 'dsymutil'.",
s))),
}
Some(Ok(()))
})).unwrap_or(Ok(()))
} );
($key_name:ident, list) => ( {
let name = (stringify!($key_name)).replace("_", "-");
if let Some(v) = obj.find(&name).and_then(Json::as_array) {
@ -1627,6 +1707,7 @@ impl Target {
key!(use_ctors_section, bool);
key!(eh_frame_header, bool);
key!(has_thumb_interworking, bool);
key!(split_debuginfo, SplitDebuginfo)?;
// NB: The old name is deprecated, but support for it is retained for
// compatibility.
@ -1862,6 +1943,7 @@ impl ToJson for Target {
target_option_val!(use_ctors_section);
target_option_val!(eh_frame_header);
target_option_val!(has_thumb_interworking);
target_option_val!(split_debuginfo);
if default.unsupported_abis != self.unsupported_abis {
d.insert(

View file

@ -1,4 +1,4 @@
use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, TargetOptions};
use crate::spec::{LinkArgs, LinkerFlavor, LldFlavor, SplitDebuginfo, TargetOptions};
pub fn opts() -> TargetOptions {
let pre_link_args_msvc = vec![
@ -27,6 +27,10 @@ pub fn opts() -> TargetOptions {
abi_return_struct_as_int: true,
emit_debug_gdb_scripts: false,
// Currently this is the only supported method of debuginfo on MSVC
// where `*.pdb` files show up next to the final artifact.
split_debuginfo: SplitDebuginfo::Packed,
..Default::default()
}
}