diff --git a/src/cargo/core/compiler/custom_build.rs b/src/cargo/core/compiler/custom_build.rs index 2ebec054791..82174c1984b 100644 --- a/src/cargo/core/compiler/custom_build.rs +++ b/src/cargo/core/compiler/custom_build.rs @@ -399,7 +399,20 @@ fn build_work(cx: &mut Context<'_, '_>, unit: &Unit) -> CargoResult { }, 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( diff --git a/src/cargo/core/profiles.rs b/src/cargo/core/profiles.rs index 75d93f50736..2549212829b 100644 --- a/src/cargo/core/profiles.rs +++ b/src/cargo/core/profiles.rs @@ -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; } // ... and next comes any other sorts of overrides specified in // profiles, such as `[profile.release.build-override]` or diff --git a/src/doc/src/reference/profiles.md b/src/doc/src/reference/profiles.md index 6885f04ffd4..3a370c57476 100644 --- a/src/doc/src/reference/profiles.md +++ b/src/doc/src/reference/profiles.md @@ -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 diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index f7dd73d076d..a5a7535672f 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -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 diff --git a/tests/testsuite/build_script.rs b/tests/testsuite/build_script.rs index d0ef3a2e727..9abd0e6c411 100644 --- a/tests/testsuite/build_script.rs +++ b/tests/testsuite/build_script.rs @@ -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 = ["wycats@example.com"] + 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() @@ -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` @@ -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", @@ -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(); }") diff --git a/tests/testsuite/dep_info.rs b/tests/testsuite/dep_info.rs index ae385b13781..dca34475b72 100644 --- a/tests/testsuite/dep_info.rs +++ b/tests/testsuite/dep_info.rs @@ -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(); @@ -255,6 +260,9 @@ fn relative_depinfo_paths_ws() { r#" [workspace] members = ["foo"] + + [profile.dev.build-override] + debug = 2 # see note above "#, ) /*********** Main Project ***********/ diff --git a/tests/testsuite/features2.rs b/tests/testsuite/features2.rs index af94073da22..bfa26b22371 100644 --- a/tests/testsuite/features2.rs +++ b/tests/testsuite/features2.rs @@ -1050,6 +1050,11 @@ 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", @@ -1057,6 +1062,9 @@ fn proc_macro_ws() { [workspace] members = ["foo", "pm"] resolver = "2" + + [profile.dev.build-override] + debug = 2 # see note above "#, ) .file( @@ -2161,6 +2169,11 @@ 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", @@ -2168,6 +2181,9 @@ fn pm_with_int_shared() { [workspace] members = ["foo", "pm", "shared"] resolver = "2" + + [profile.dev.build-override] + debug = 2 # see note above "#, ) .file( diff --git a/tests/testsuite/freshness.rs b/tests/testsuite/freshness.rs index 1927a690aa3..013575c1ecf 100644 --- a/tests/testsuite/freshness.rs +++ b/tests/testsuite/freshness.rs @@ -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", @@ -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", "") @@ -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 [..] diff --git a/tests/testsuite/proc_macro.rs b/tests/testsuite/proc_macro.rs index 50e432a19c8..9f66eb159d5 100644 --- a/tests/testsuite/proc_macro.rs +++ b/tests/testsuite/proc_macro.rs @@ -498,6 +498,10 @@ 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", @@ -505,6 +509,9 @@ fn proc_macro_built_once() { [workspace] members = ['a', 'b'] resolver = "2" + + [profile.dev.build-override] + debug = 2 # see note above "#, ) .file( diff --git a/tests/testsuite/profile_config.rs b/tests/testsuite/profile_config.rs index 93e76d4c0c1..046622d36d6 100644 --- a/tests/testsuite/profile_config.rs +++ b/tests/testsuite/profile_config.rs @@ -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 diff --git a/tests/testsuite/profile_overrides.rs b/tests/testsuite/profile_overrides.rs index 661fada49c8..5a6b8554b13 100644 --- a/tests/testsuite/profile_overrides.rs +++ b/tests/testsuite/profile_overrides.rs @@ -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", @@ -153,6 +156,7 @@ fn profile_override_hierarchy() { [profile.dev.build-override] codegen-units = 4 + debug = 2 # see note above "#, ) // m1 diff --git a/tests/testsuite/profile_targets.rs b/tests/testsuite/profile_targets.rs index 74d54385ff1..051248454d8 100644 --- a/tests/testsuite/profile_targets.rs +++ b/tests/testsuite/profile_targets.rs @@ -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 [..] @@ -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 [..]` @@ -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 [..] @@ -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 [..] @@ -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 [..] @@ -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 [..]