Skip to content

Turn off debuginfo for build dependencies to improve compile times #10493

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 10 commits into from
15 changes: 14 additions & 1 deletion src/cargo/core/compiler/custom_build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,20 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult<Job> {
},
true,
)
.with_context(|| format!("failed to run custom build command for `{}`", pkg_descr));
.with_context(|| {
let mut build_error_context = format!("failed to run custom build command for `{}`", pkg_descr);

// If we're opting into backtraces, mention that build dependencies' backtraces can
// be improved by setting a higher debuginfo level.
if let Ok(show_backtraces) = std::env::var("RUST_BACKTRACE") {
if show_backtraces != "0" {
build_error_context.push_str("\n\
note: To improve backtraces for build dependencies, make sure full debug info is turned on. More details at https://doc.rust-lang.org/cargo/reference/profiles.html#build-dependencies");
}
}

build_error_context
});

if let Err(error) = output {
insert_warnings_in_build_outputs(
Expand Down
3 changes: 3 additions & 0 deletions src/cargo/core/profiles.rs
Original file line number Diff line number Diff line change
Expand Up @@ -408,8 +408,11 @@ impl ProfileMaker {
// basically turning down the optimization level and avoid limiting
// codegen units. This ensures that we spend little time optimizing as
// well as enabling parallelism by not constraining codegen units.
// Turning off debuginfo also allows the compiler to noticeably perform
// less work.
profile.opt_level = InternedString::new("0");
profile.codegen_units = None;
profile.debuginfo = None;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this also add strip = "debuginfo" on all platforms but macOS?

Copy link
Member Author

@lqd lqd Mar 21, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

the cargo team asked not to have strip for now in this message.

(incidentally, a friend tried the defaults I suggested and his project saw weird errors about unstable -Z flags being used on a stable compiler, because of stripping on android, so I'm not sure that all targets can use it rn)

}
// ... and next comes any other sorts of overrides specified in
// profiles, such as `[profile.release.build-override]` or
Expand Down
15 changes: 12 additions & 3 deletions src/doc/src/reference/profiles.md
Original file line number Diff line number Diff line change
Expand Up @@ -298,18 +298,27 @@ The `bench` profile inherits the settings from the [`release`](#release) profile

#### Build Dependencies

All profiles, by default, do not optimize build dependencies (build scripts,
proc macros, and their dependencies). The default settings for build overrides
are:
To compile quickly, all profiles, by default, do not optimize build
dependencies (build scripts, proc macros, and their dependencies), and avoid
computing debug info. The default settings for build overrides are:

```toml
[profile.dev.build-override]
opt-level = 0
codegen-units = 256
debug = false

[profile.release.build-override]
opt-level = 0
codegen-units = 256
debug = false
```

However, if errors occur while running build dependencies, turning full debug
info on will improve backtraces and debuggability when needed:

```toml
debug = true
```

Build dependencies otherwise inherit settings from the active profile in use, as
Expand Down
2 changes: 1 addition & 1 deletion tests/testsuite/build.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3777,7 +3777,7 @@ fn compiler_json_error_format() {
},
"profile": {
"debug_assertions": true,
"debuginfo": 2,
"debuginfo": null,
"opt_level": "0",
"overflow_checks": true,
"test": false
Expand Down
48 changes: 46 additions & 2 deletions tests/testsuite/build_script.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,43 @@ Caused by:
.run();
}

#[cargo_test]
fn custom_build_script_failed_backtraces_message() {
// debuginfo is turned off by default in `dev.build-override`. However,
// if an error occurs running e.g. a build script, a message explaining
// how to improve backtraces is also displayed.
let p = project()
.file(
"Cargo.toml",
r#"
[project]

name = "foo"
version = "0.5.0"
authors = ["[email protected]"]
build = "build.rs"
"#,
)
.file("src/main.rs", "fn main() {}")
.file("build.rs", "fn main() { std::process::exit(101); }")
.build();
p.cargo("build -v")
.env("RUST_BACKTRACE", "1")
.with_status(101)
.with_stderr(
"\
[COMPILING] foo v0.5.0 ([CWD])
[RUNNING] `rustc --crate-name build_script_build build.rs [..]--crate-type bin [..]`
[RUNNING] `[..]/build-script-build`
[ERROR] failed to run custom build command for `foo v0.5.0 ([CWD])`
note: To improve backtraces for build dependencies[..]

Caused by:
process didn't exit successfully: `[..]/build-script-build` (exit [..]: 101)",
)
.run();
}

#[cargo_test]
fn custom_build_env_vars() {
let p = project()
Expand Down Expand Up @@ -1629,14 +1666,14 @@ fn build_cmd_with_a_build_cmd() {
[RUNNING] `rustc [..] a/build.rs [..] --extern b=[..]`
[RUNNING] `[..]/a-[..]/build-script-build`
[RUNNING] `rustc --crate-name a [..]lib.rs [..]--crate-type lib \
--emit=[..]link[..]-C debuginfo=2 \
--emit=[..]link[..] \
-C metadata=[..] \
--out-dir [..]target/debug/deps \
-L [..]target/debug/deps`
[COMPILING] foo v0.5.0 ([CWD])
[RUNNING] `rustc --crate-name build_script_build build.rs [..]--crate-type bin \
--emit=[..]link[..]\
-C debuginfo=2 -C metadata=[..] --out-dir [..] \
-C metadata=[..] --out-dir [..] \
-L [..]target/debug/deps \
--extern a=[..]liba[..].rlib`
[RUNNING] `[..]/foo-[..]/build-script-build`
Expand Down Expand Up @@ -4379,6 +4416,10 @@ fn optional_build_script_dep() {

#[cargo_test]
fn optional_build_dep_and_required_normal_dep() {
// Note: `dev` and `dev.build-override` have different defaults. `bar` would
// be built twice in the general case: once without debuginfo and once with
// debuginfo = 2. Setting `debug = 2` in `dev.build-override` ensures it's
// only built once in this test.
let p = project()
.file(
"Cargo.toml",
Expand All @@ -4393,6 +4434,9 @@ fn optional_build_dep_and_required_normal_dep() {

[build-dependencies]
bar = { path = "./bar" }

[profile.dev.build-override]
debug = 2 # see note above
"#,
)
.file("build.rs", "extern crate bar; fn main() { bar::bar(); }")
Expand Down
8 changes: 8 additions & 0 deletions tests/testsuite/dep_info.rs
Original file line number Diff line number Diff line change
Expand Up @@ -238,6 +238,11 @@ fn relative_depinfo_paths_ws() {

// Test relative dep-info paths in a workspace with --target with
// proc-macros and other dependency kinds.
//
// Note: `dev` and `dev.build-override` have different defaults. `pmdep`
// would be built twice in the general case: once without debuginfo and once
// with debuginfo = 2. Setting `debug = 2` in `dev.build-override` ensures
// it will only create a single dep-info file.
Package::new("regdep", "0.1.0")
.file("src/lib.rs", "pub fn f() {}")
.publish();
Expand All @@ -255,6 +260,9 @@ fn relative_depinfo_paths_ws() {
r#"
[workspace]
members = ["foo"]

[profile.dev.build-override]
debug = 2 # see note above
"#,
)
/*********** Main Project ***********/
Expand Down
16 changes: 16 additions & 0 deletions tests/testsuite/features2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1050,13 +1050,21 @@ fn decouple_proc_macro() {
#[cargo_test]
fn proc_macro_ws() {
// Checks for bug with proc-macro in a workspace with dependency (shouldn't panic).
//
// Note, `dev` and `dev.build-override` have different defaults. `pm` would
// be built twice in the general case: once without debuginfo and once with
// debuginfo = 2. Setting `debug = 2` in `dev.build-override` ensures it's
// only built once and `foo` remains fresh during the second check build.
let p = project()
.file(
"Cargo.toml",
r#"
[workspace]
members = ["foo", "pm"]
resolver = "2"

[profile.dev.build-override]
debug = 2 # see note above
"#,
)
.file(
Expand Down Expand Up @@ -2161,13 +2169,21 @@ fn pm_with_int_shared() {
// with `--workspace`, see https://github.com/rust-lang/cargo/issues/8312.
//
// This uses a const-eval hack to do compile-time feature checking.
//
// Note, `dev` and `dev.build-override` have different defaults. `pm` would
// be built twice in the general case: once without debuginfo and once with
// debuginfo = 2. Setting `debug = 2` in `dev.build-override` ensures it's
// only built once in this test.
let p = project()
.file(
"Cargo.toml",
r#"
[workspace]
members = ["foo", "pm", "shared"]
resolver = "2"

[profile.dev.build-override]
debug = 2 # see note above
"#,
)
.file(
Expand Down
9 changes: 8 additions & 1 deletion tests/testsuite/freshness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1344,6 +1344,10 @@ fn fingerprint_cleaner_does_not_rebuild() {

#[cargo_test]
fn reuse_panic_build_dep_test() {
// Note: `dev` and `dev.build-override` have different defaults. `bar` would
// be built twice in the general case: once without debuginfo and once with
// debuginfo = 2. Setting `debug = 2` in `dev.build-override` ensures it's
// only built once in this test.
let p = project()
.file(
"Cargo.toml",
Expand All @@ -1360,6 +1364,9 @@ fn reuse_panic_build_dep_test() {

[profile.dev]
panic = "abort"

[profile.dev.build-override]
debug = 2 # see note above
"#,
)
.file("src/lib.rs", "")
Expand Down Expand Up @@ -1431,7 +1438,7 @@ fn reuse_panic_pm() {
.with_stderr_unordered(
"\
[COMPILING] bar [..]
[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C debuginfo=2 [..]
[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]
[RUNNING] `rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort[..]-C debuginfo=2 [..]
[COMPILING] somepm [..]
[RUNNING] `rustc --crate-name somepm [..]
Expand Down
7 changes: 7 additions & 0 deletions tests/testsuite/proc_macro.rs
Original file line number Diff line number Diff line change
Expand Up @@ -498,13 +498,20 @@ fn proc_macro_extern_prelude() {

#[cargo_test]
fn proc_macro_built_once() {
// Note: `dev` and `dev.build-override` have different defaults. `the-macro`
// would be built twice in the general case: once without debuginfo and once
// with debuginfo = 2. Setting `debug = 2` in `dev.build-override` ensures
// it's only built once in this test.
let p = project()
.file(
"Cargo.toml",
r#"
[workspace]
members = ['a', 'b']
resolver = "2"

[profile.dev.build-override]
debug = 2 # see note above
"#,
)
.file(
Expand Down
2 changes: 1 addition & 1 deletion tests/testsuite/profile_config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -384,7 +384,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, Some(1)); // SAME as normal
assert_eq!(bo.debuginfo, None); // default to none
assert_eq!(bo.debug_assertions, false); // "foo" build override from manifest
assert_eq!(bo.overflow_checks, true); // SAME as normal

Expand Down
4 changes: 4 additions & 0 deletions tests/testsuite/profile_overrides.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,9 @@ fn profile_override_bad_settings() {
#[cargo_test]
fn profile_override_hierarchy() {
// Test that the precedence rules are correct for different types.
// Note, `dev` and `dev.build-override` have different defaults. `dep` would be built twice in
// the general case: once without debuginfo and once with debuginfo = 2. Setting `debug = 2` in
// `dev.build-override` ensures it's only built once in this test.
let p = project()
.file(
"Cargo.toml",
Expand All @@ -153,6 +156,7 @@ fn profile_override_hierarchy() {

[profile.dev.build-override]
codegen-units = 4
debug = 2 # see note above
"#,
)
// m1
Expand Down
36 changes: 18 additions & 18 deletions tests/testsuite/profile_targets.rs
Original file line number Diff line number Diff line change
Expand Up @@ -85,11 +85,11 @@ fn profile_selection_build() {
p.cargo("build -vv").with_stderr_unordered("\
[COMPILING] bar [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort[..]-C codegen-units=1 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 [..]
[COMPILING] bdep [..]
[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 [..]
[COMPILING] foo [..]
[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link[..]-C codegen-units=5 [..]
[RUNNING] `[..]/target/debug/build/foo-[..]/build-script-build`
[foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0
[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort[..]-C codegen-units=1 -C debuginfo=2 [..]
Expand Down Expand Up @@ -173,11 +173,11 @@ fn profile_selection_build_all_targets() {
[COMPILING] bar [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=1 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort[..]-C codegen-units=1 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 [..]
[COMPILING] bdep [..]
[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 [..]
[COMPILING] foo [..]
[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link[..]-C codegen-units=5 [..]
[RUNNING] `[..]/target/debug/build/foo-[..]/build-script-build`
[foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0
[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort[..]-C codegen-units=1 -C debuginfo=2 [..]`
Expand Down Expand Up @@ -295,12 +295,12 @@ fn profile_selection_test() {
p.cargo("test -vv").with_stderr_unordered("\
[COMPILING] bar [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=3 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort[..]-C codegen-units=3 -C debuginfo=2 [..]
[COMPILING] bdep [..]
[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 [..]
[COMPILING] foo [..]
[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link[..]-C codegen-units=5 [..]
[RUNNING] `[..]/target/debug/build/foo-[..]/build-script-build`
[foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0
[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]link -C panic=abort[..]-C codegen-units=3 -C debuginfo=2 [..]
Expand Down Expand Up @@ -492,13 +492,13 @@ fn profile_selection_check_all_targets() {
//
p.cargo("check --all-targets -vv").with_stderr_unordered("\
[COMPILING] bar [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]metadata[..]-C codegen-units=1 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]metadata -C panic=abort[..]-C codegen-units=1 -C debuginfo=2 [..]
[COMPILING] bdep[..]
[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 [..]
[COMPILING] foo [..]
[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link[..]-C codegen-units=5 [..]
[RUNNING] `[..]target/debug/build/foo-[..]/build-script-build`
[foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0
[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]metadata -C panic=abort[..]-C codegen-units=1 -C debuginfo=2 [..]
Expand Down Expand Up @@ -596,12 +596,12 @@ fn profile_selection_check_all_targets_test() {
//
p.cargo("check --all-targets --profile=test -vv").with_stderr_unordered("\
[COMPILING] bar [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]metadata[..]-C codegen-units=3 -C debuginfo=2 [..]
[COMPILING] bdep[..]
[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 [..]
[COMPILING] foo [..]
[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link[..]-C codegen-units=5 [..]
[RUNNING] `[..]target/debug/build/foo-[..]/build-script-build`
[foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0
[RUNNING] `[..] rustc --crate-name foo src/lib.rs [..]--crate-type lib --emit=[..]metadata[..]-C codegen-units=3 -C debuginfo=2 [..]
Expand Down Expand Up @@ -642,13 +642,13 @@ fn profile_selection_doc() {
p.cargo("doc -vv").with_stderr_unordered("\
[COMPILING] bar [..]
[DOCUMENTING] bar [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 [..]
[RUNNING] `rustdoc [..]--crate-name bar bar/src/lib.rs [..]
[RUNNING] `[..] rustc --crate-name bar bar/src/lib.rs [..]--crate-type lib --emit=[..]metadata -C panic=abort[..]-C codegen-units=1 -C debuginfo=2 [..]
[COMPILING] bdep [..]
[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name bdep bdep/src/lib.rs [..]--crate-type lib --emit=[..]link[..]-C codegen-units=5 [..]
[COMPILING] foo [..]
[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link[..]-C codegen-units=5 -C debuginfo=2 [..]
[RUNNING] `[..] rustc --crate-name build_script_build build.rs [..]--crate-type bin --emit=[..]link[..]-C codegen-units=5 [..]
[RUNNING] `[..]target/debug/build/foo-[..]/build-script-build`
[foo 0.0.1] foo custom build PROFILE=debug DEBUG=true OPT_LEVEL=0
[DOCUMENTING] foo [..]
Expand Down