Default macOS targets to `unpacked` debuginfo

This commit continues the work from #9112 to enable `unpacked` split
debuginfo on macOS targets by default. This has been discussed on [internals]
for awhile now and no breakage has emerged while significant speedups
have. This is expected to be a compile-time and `target`-directory size
win for almost all macOS Rust projects.

While breakage is possible it's possible to mitigate this with
project-local or global cargo configuration of the `dev` and `test` profiles.

[internals]: https://internals.rust-lang.org/t/help-test-faster-incremental-debug-macos-builds-on-nightly/14016/9
This commit is contained in:
Alex Crichton 2021-03-24 14:04:56 -07:00
parent 58a9613144
commit a4f0988ef8
7 changed files with 47 additions and 31 deletions

View File

@ -1614,14 +1614,6 @@ fn _process(t: &OsStr) -> ProcessBuilder {
p.env("PATH", new_path);
}
if cfg!(target_os = "macos") {
// This makes the test suite run substantially faster.
p.env("CARGO_PROFILE_DEV_SPLIT_DEBUGINFO", "unpacked")
.env("CARGO_PROFILE_TEST_SPLIT_DEBUGINFO", "unpacked")
.env("CARGO_PROFILE_RELEASE_SPLIT_DEBUGINFO", "unpacked")
.env("CARGO_PROFILE_BENCH_SPLIT_DEBUGINFO", "unpacked");
}
p.cwd(&paths::root())
.env("HOME", paths::home())
.env("CARGO_HOME", paths::home().join(".cargo"))

View File

@ -158,17 +158,18 @@ pub fn generate_std_roots(
// in time is minimal, and the difference in caching is
// significant.
let mode = CompileMode::Build;
let profile = profiles.get_profile(
pkg.package_id(),
/*is_member*/ false,
/*is_local*/ false,
unit_for,
mode,
);
let features = std_features.activated_features(pkg.package_id(), FeaturesFor::NormalOrDev);
for kind in kinds {
let list = ret.entry(*kind).or_insert_with(Vec::new);
let profile = profiles.get_profile(
pkg.package_id(),
/*is_member*/ false,
/*is_local*/ false,
unit_for,
mode,
*kind,
);
list.push(interner.intern(
pkg,
lib,

View File

@ -585,6 +585,7 @@ fn new_unit_dep(
is_local,
unit_for,
mode,
kind,
);
new_unit_dep_with_profile(state, parent, pkg, target, unit_for, kind, mode, profile)
}

View File

@ -1,4 +1,4 @@
use crate::core::compiler::{CompileMode, Unit};
use crate::core::compiler::{CompileKind, CompileMode, Unit};
use crate::core::resolver::features::FeaturesFor;
use crate::core::{Feature, PackageId, PackageIdSpec, Resolve, Shell, Target, Workspace};
use crate::util::errors::CargoResultExt;
@ -291,6 +291,7 @@ impl Profiles {
is_local: bool,
unit_for: UnitFor,
mode: CompileMode,
kind: CompileKind,
) -> Profile {
let (profile_name, inherits) = if !self.named_profiles_enabled {
// With the feature disabled, we degrade `--profile` back to the
@ -346,6 +347,23 @@ impl Profiles {
}
}
// Default macOS debug information to being stored in the "unpacked"
// split-debuginfo format. At the time of this writing that's the only
// 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 {
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"));
}
}
}
// Incremental can be globally overridden.
if let Some(v) = self.incremental {
profile.incremental = v;

View File

@ -909,19 +909,20 @@ fn generate_targets(
};
let is_local = pkg.package_id().source_id().is_path();
let profile = profiles.get_profile(
pkg.package_id(),
ws.is_member(pkg),
is_local,
unit_for,
target_mode,
);
// No need to worry about build-dependencies, roots are never build dependencies.
let features_for = FeaturesFor::from_for_host(target.proc_macro());
let features = resolved_features.activated_features(pkg.package_id(), features_for);
for kind in requested_kinds {
let profile = profiles.get_profile(
pkg.package_id(),
ws.is_member(pkg),
is_local,
unit_for,
target_mode,
*kind,
);
let unit = interner.intern(
pkg,
target,

View File

@ -83,10 +83,12 @@ controls whether debug information, if generated, is either placed in the
executable itself or adjacent to it.
This option is a string and acceptable values are the same as those the
[compiler accepts][`-C split-debuginfo` flag]. See that documentation for the
default behavior, which is platform-specific. Some options are only available
on the [nightly channel]. The default may change in the future once more
testing has been performed, and support for DWARF is stabilized.
[compiler accepts][`-C split-debuginfo` flag]. The default value for this option
is `unpacked` on macOS for profiles that have debug information otherwise
enabled. Otherwise the default for this option is [documented with rustc][`-C
split-debuginfo` flag] and is platform-specific. Some options are only
available on the [nightly channel]. The Cargo default may change in the future
once more testing has been performed, and support for DWARF is stabilized.
[nightly channel]: ../../book/appendix-07-nightly-rust.html
[`-C split-debuginfo` flag]: ../../rustc/codegen-options/index.html#split-debuginfo

View File

@ -342,7 +342,7 @@ fn named_config_profile() {
// foo -> middle -> bar -> dev
// middle exists in Cargo.toml, the others in .cargo/config
use super::config::ConfigBuilder;
use cargo::core::compiler::CompileMode;
use cargo::core::compiler::{CompileKind, CompileMode};
use cargo::core::profiles::{Profiles, UnitFor};
use cargo::core::{PackageId, Workspace};
use cargo::util::interning::InternedString;
@ -403,7 +403,8 @@ fn named_config_profile() {
// normal package
let mode = CompileMode::Build;
let p = profiles.get_profile(a_pkg, true, true, UnitFor::new_normal(), mode);
let kind = CompileKind::Host;
let p = profiles.get_profile(a_pkg, true, true, UnitFor::new_normal(), mode, kind);
assert_eq!(p.name, "foo");
assert_eq!(p.codegen_units, Some(2)); // "foo" from config
assert_eq!(p.opt_level, "1"); // "middle" from manifest
@ -412,7 +413,7 @@ fn named_config_profile() {
assert_eq!(p.overflow_checks, true); // "dev" built-in (ignore package override)
// build-override
let bo = profiles.get_profile(a_pkg, true, true, UnitFor::new_host(false), mode);
let bo = profiles.get_profile(a_pkg, true, true, UnitFor::new_host(false), mode, kind);
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
@ -421,7 +422,7 @@ fn named_config_profile() {
assert_eq!(bo.overflow_checks, true); // SAME as normal
// package overrides
let po = profiles.get_profile(dep_pkg, false, true, UnitFor::new_normal(), mode);
let po = profiles.get_profile(dep_pkg, false, true, UnitFor::new_normal(), mode, kind);
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