From ed4568e108cdc371b60bb84828c50d16197ba6d7 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 29 Jan 2021 13:24:56 -0800 Subject: [PATCH 1/3] Add split-debuginfo profile option This commit adds a new `split-debuginfo` option to Cargo compilation profiles which gets forwarded to the `-Csplit-debuginfo` codegen option in rustc. This commit also sets the default, only on macOS, to be `-Csplit-debuginfo=unpacked`. The purpose of this change is to leverage rust-lang/rust#79570 to avoid running `dsymutil` on incremental builds while also preserving a pleasant debugging experience by default. This should lead to much faster incremental build times on macOS since `dsymutil` isn't exactly the speediest tool in the world. This is technically a breaking change in Cargo because we're no longer by-default producing the `*.dSYM` folders on macOS. If those are still desired, however, authors can always run `dsymutil` themselves or otherwise configure `split-debuginfo = 'packed'` in their manifest/profile configuration. --- crates/cargo-test-support/src/lib.rs | 10 ++ .../compiler/build_context/target_info.rs | 6 + src/cargo/core/compiler/mod.rs | 10 ++ src/cargo/core/compiler/standard_lib.rs | 15 +-- src/cargo/core/compiler/unit_dependencies.rs | 1 + src/cargo/core/profiles.rs | 86 +++++++------ src/cargo/ops/cargo_clean.rs | 14 +-- src/cargo/ops/cargo_compile.rs | 22 ++-- src/cargo/util/toml/mod.rs | 5 + src/doc/src/reference/profiles.md | 18 +++ tests/testsuite/build.rs | 8 +- tests/testsuite/out_dir.rs | 5 + tests/testsuite/profile_config.rs | 114 ++++++++++-------- tests/testsuite/rustc_info_cache.rs | 5 + tests/testsuite/unit_graph.rs | 12 +- 15 files changed, 212 insertions(+), 119 deletions(-) diff --git a/crates/cargo-test-support/src/lib.rs b/crates/cargo-test-support/src/lib.rs index 14e8e8d27ff..f12f935fa78 100644 --- a/crates/cargo-test-support/src/lib.rs +++ b/crates/cargo-test-support/src/lib.rs @@ -722,6 +722,16 @@ impl Execs { self } + pub fn enable_mac_dsym(&mut self) -> &mut Self { + if cfg!(target_os = "macos") { + self.env("CARGO_PROFILE_DEV_SPLIT_DEBUGINFO", "packed") + .env("CARGO_PROFILE_TEST_SPLIT_DEBUGINFO", "packed") + .env("CARGO_PROFILE_RELEASE_SPLIT_DEBUGINFO", "packed") + .env("CARGO_PROFILE_BENCH_SPLIT_DEBUGINFO", "packed"); + } + self + } + pub fn run(&mut self) { self.ran = true; let p = (&self.process_builder).clone().unwrap(); diff --git a/src/cargo/core/compiler/build_context/target_info.rs b/src/cargo/core/compiler/build_context/target_info.rs index f37d0ef5bcf..9d205d0e212 100644 --- a/src/cargo/core/compiler/build_context/target_info.rs +++ b/src/cargo/core/compiler/build_context/target_info.rs @@ -40,6 +40,8 @@ pub struct TargetInfo { pub rustflags: Vec, /// Extra flags to pass to `rustdoc`, see `env_args`. pub rustdocflags: Vec, + /// Whether or not rustc supports the `-Csplit-debuginfo` flag. + pub supports_split_debuginfo: bool, } /// Kind of each file generated by a Unit, part of `FileType`. @@ -157,6 +159,9 @@ impl TargetInfo { for crate_type in KNOWN_CRATE_TYPES.iter() { process.arg("--crate-type").arg(crate_type.as_str()); } + let supports_split_debuginfo = rustc + .cached_output(process.clone().arg("-Csplit-debuginfo=packed")) + .is_ok(); process.arg("--print=sysroot"); process.arg("--print=cfg"); @@ -231,6 +236,7 @@ impl TargetInfo { "RUSTDOCFLAGS", )?, cfg, + supports_split_debuginfo, }) } diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index 34e92afba62..d2cd60b2c79 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -773,6 +773,7 @@ fn build_base_args( codegen_units, debuginfo, debug_assertions, + split_debuginfo, overflow_checks, rpath, ref panic, @@ -825,6 +826,15 @@ fn build_base_args( cmd.args(<o_args(cx, unit)); + // This is generally just an optimization on build time so if we don't pass + // it then it's ok. As of the time of this writing it's a very new flag, so + // we need to dynamically check if it's available. + if cx.bcx.target_data.info(unit.kind).supports_split_debuginfo { + if let Some(split) = split_debuginfo { + cmd.arg("-C").arg(format!("split-debuginfo={}", split)); + } + } + if let Some(n) = codegen_units { cmd.arg("-C").arg(&format!("codegen-units={}", n)); } diff --git a/src/cargo/core/compiler/standard_lib.rs b/src/cargo/core/compiler/standard_lib.rs index 0b14df8055a..67d6189304b 100644 --- a/src/cargo/core/compiler/standard_lib.rs +++ b/src/cargo/core/compiler/standard_lib.rs @@ -162,16 +162,17 @@ 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 profile = profiles.get_profile( + pkg.package_id(), + /*is_member*/ false, + /*is_local*/ false, + unit_for, + mode, + *kind, + ); let list = ret.entry(*kind).or_insert_with(Vec::new); list.push(interner.intern( pkg, diff --git a/src/cargo/core/compiler/unit_dependencies.rs b/src/cargo/core/compiler/unit_dependencies.rs index 9445bb8861e..22c29c66f34 100644 --- a/src/cargo/core/compiler/unit_dependencies.rs +++ b/src/cargo/core/compiler/unit_dependencies.rs @@ -593,6 +593,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) } diff --git a/src/cargo/core/profiles.rs b/src/cargo/core/profiles.rs index 6be64a38ff1..b65832407ba 100644 --- a/src/cargo/core/profiles.rs +++ b/src/cargo/core/profiles.rs @@ -1,12 +1,13 @@ -use crate::core::compiler::{CompileMode, Unit}; +use crate::core::compiler::{CompileKind, CompileMode, Unit}; use crate::core::resolver::features::FeaturesFor; -use crate::core::{Feature, Features, PackageId, PackageIdSpec, Resolve, Shell, Target}; +use crate::core::{Feature, PackageId, PackageIdSpec, Resolve, Shell, Target, Workspace}; use crate::util::errors::CargoResultExt; use crate::util::interning::InternedString; use crate::util::toml::{ProfilePackageSpec, StringOrBool, TomlProfile, TomlProfiles, U32OrBool}; use crate::util::{closest_msg, config, CargoResult, Config}; use anyhow::bail; use std::collections::{BTreeMap, HashMap, HashSet}; +use std::hash::Hash; use std::{cmp, env, fmt, hash}; /// Collection of all profiles. @@ -24,28 +25,28 @@ pub struct Profiles { named_profiles_enabled: bool, /// The profile the user requested to use. requested_profile: InternedString, + /// The host target for rustc being used by this `Profiles`. + rustc_host: InternedString, } impl Profiles { - pub fn new( - profiles: Option<&TomlProfiles>, - config: &Config, - requested_profile: InternedString, - features: &Features, - ) -> CargoResult { + pub fn new(ws: &Workspace<'_>, requested_profile: InternedString) -> CargoResult { + let config = ws.config(); let incremental = match env::var_os("CARGO_INCREMENTAL") { Some(v) => Some(v == "1"), None => config.build_config()?.incremental, }; - let mut profiles = merge_config_profiles(profiles, config, requested_profile, features)?; + let mut profiles = merge_config_profiles(ws, requested_profile)?; + let rustc_host = ws.config().load_global_rustc(Some(ws))?.host; - if !features.is_enabled(Feature::named_profiles()) { + if !ws.unstable_features().is_enabled(Feature::named_profiles()) { let mut profile_makers = Profiles { incremental, named_profiles_enabled: false, dir_names: Self::predefined_dir_names(), by_name: HashMap::new(), requested_profile, + rustc_host, }; profile_makers.by_name.insert( @@ -98,6 +99,7 @@ impl Profiles { dir_names: Self::predefined_dir_names(), by_name: HashMap::new(), requested_profile, + rustc_host, }; Self::add_root_profiles(&mut profile_makers, &profiles); @@ -289,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 @@ -344,10 +347,28 @@ impl Profiles { } } + // Default macOS debug information to being stored in the "packed" + // 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; } + // Only enable incremental compilation for sources the user can // modify (aka path sources). For things that change infrequently, // non-incremental builds yield better performance in the compiler @@ -567,6 +588,9 @@ fn merge_profile(profile: &mut Profile, toml: &TomlProfile) { if let Some(debug_assertions) = toml.debug_assertions { profile.debug_assertions = debug_assertions; } + if let Some(split_debuginfo) = &toml.split_debuginfo { + profile.split_debuginfo = Some(InternedString::new(split_debuginfo)); + } if let Some(rpath) = toml.rpath { profile.rpath = rpath; } @@ -612,6 +636,7 @@ pub struct Profile { // `None` means use rustc default. pub codegen_units: Option, pub debuginfo: Option, + pub split_debuginfo: Option, pub debug_assertions: bool, pub overflow_checks: bool, pub rpath: bool, @@ -630,6 +655,7 @@ impl Default for Profile { codegen_units: None, debuginfo: None, debug_assertions: false, + split_debuginfo: None, overflow_checks: false, rpath: false, incremental: false, @@ -654,6 +680,7 @@ compact_debug! { root codegen_units debuginfo + split_debuginfo debug_assertions overflow_checks rpath @@ -734,25 +761,13 @@ impl Profile { /// Compares all fields except `name`, which doesn't affect compilation. /// This is necessary for `Unit` deduplication for things like "test" and /// "dev" which are essentially the same. - fn comparable( - &self, - ) -> ( - InternedString, - Lto, - Option, - Option, - bool, - bool, - bool, - bool, - PanicStrategy, - Strip, - ) { + fn comparable(&self) -> impl Hash + Eq { ( self.opt_level, self.lto, self.codegen_units, self.debuginfo, + self.split_debuginfo, self.debug_assertions, self.overflow_checks, self.rpath, @@ -1073,12 +1088,10 @@ impl UnitFor { /// /// Returns a new copy of the profile map with all the mergers complete. fn merge_config_profiles( - profiles: Option<&TomlProfiles>, - config: &Config, + ws: &Workspace<'_>, requested_profile: InternedString, - features: &Features, ) -> CargoResult> { - let mut profiles = match profiles { + let mut profiles = match ws.profiles() { Some(profiles) => profiles.get_all().clone(), None => BTreeMap::new(), }; @@ -1087,7 +1100,7 @@ fn merge_config_profiles( check_to_add.insert(requested_profile); // Merge config onto manifest profiles. for (name, profile) in &mut profiles { - if let Some(config_profile) = get_config_profile(name, config, features)? { + if let Some(config_profile) = get_config_profile(ws, name)? { profile.merge(&config_profile); } if let Some(inherits) = &profile.inherits { @@ -1106,7 +1119,7 @@ fn merge_config_profiles( std::mem::swap(&mut current, &mut check_to_add); for name in current.drain() { if !profiles.contains_key(&name) { - if let Some(config_profile) = get_config_profile(&name, config, features)? { + if let Some(config_profile) = get_config_profile(ws, &name)? { if let Some(inherits) = &config_profile.inherits { check_to_add.insert(*inherits); } @@ -1119,12 +1132,9 @@ fn merge_config_profiles( } /// Helper for fetching a profile from config. -fn get_config_profile( - name: &str, - config: &Config, - features: &Features, -) -> CargoResult> { - let profile: Option> = config.get(&format!("profile.{}", name))?; +fn get_config_profile(ws: &Workspace<'_>, name: &str) -> CargoResult> { + let profile: Option> = + ws.config().get(&format!("profile.{}", name))?; let profile = match profile { Some(profile) => profile, None => return Ok(None), @@ -1132,7 +1142,7 @@ fn get_config_profile( let mut warnings = Vec::new(); profile .val - .validate(name, features, &mut warnings) + .validate(name, ws.unstable_features(), &mut warnings) .chain_err(|| { anyhow::format_err!( "config profile `{}` is not valid (defined in `{}`)", @@ -1141,7 +1151,7 @@ fn get_config_profile( ) })?; for warning in warnings { - config.shell().warn(warning)?; + ws.config().shell().warn(warning)?; } Ok(Some(profile.val)) } diff --git a/src/cargo/ops/cargo_clean.rs b/src/cargo/ops/cargo_clean.rs index ba5daad5921..6680d7a06d8 100644 --- a/src/cargo/ops/cargo_clean.rs +++ b/src/cargo/ops/cargo_clean.rs @@ -35,12 +35,7 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> { return rm_rf(&target_dir.into_path_unlocked(), config); } - let profiles = Profiles::new( - ws.profiles(), - config, - opts.requested_profile, - ws.unstable_features(), - )?; + let profiles = Profiles::new(ws, opts.requested_profile)?; if opts.profile_specified { // After parsing profiles we know the dir-name of the profile, if a profile @@ -181,9 +176,14 @@ pub fn clean(ws: &Workspace<'_>, opts: &CleanOptions<'_>) -> CargoResult<()> { // Remove dep-info file generated by rustc. It is not tracked in // file_types. It does not have a prefix. let hashed_dep_info = dir.join(format!("{}-*.d", crate_name)); - let unhashed_dep_info = dir.join(format!("{}.d", crate_name)); rm_rf_glob(&hashed_dep_info, config)?; + let unhashed_dep_info = dir.join(format!("{}.d", crate_name)); rm_rf(&unhashed_dep_info, config)?; + // Remove split-debuginfo files generated by rustc. + let split_debuginfo_obj = dir.join(format!("{}.*.o", crate_name)); + rm_rf_glob(&split_debuginfo_obj, config)?; + let split_debuginfo_dwo = dir.join(format!("{}.*.dwo", crate_name)); + rm_rf_glob(&split_debuginfo_dwo, config)?; // Remove the uplifted copy. if let Some(uplift_dir) = uplift_dir { diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 9068fe4903f..2a32ad7b2f7 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -429,12 +429,7 @@ pub fn create_bcx<'a, 'cfg>( ); } - let profiles = Profiles::new( - ws.profiles(), - config, - build_config.requested_profile, - ws.unstable_features(), - )?; + let profiles = Profiles::new(ws, build_config.requested_profile)?; profiles.validate_packages( ws.profiles(), &mut config.shell(), @@ -887,19 +882,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.for_target(target), + ); let unit = interner.intern( pkg, target, diff --git a/src/cargo/util/toml/mod.rs b/src/cargo/util/toml/mod.rs index 24f362ce75f..db54c9fd045 100644 --- a/src/cargo/util/toml/mod.rs +++ b/src/cargo/util/toml/mod.rs @@ -432,6 +432,7 @@ pub struct TomlProfile { pub lto: Option, pub codegen_units: Option, pub debug: Option, + pub split_debuginfo: Option, pub debug_assertions: Option, pub rpath: Option, pub panic: Option, @@ -634,6 +635,10 @@ impl TomlProfile { self.debug_assertions = Some(v); } + if let Some(v) = &profile.split_debuginfo { + self.split_debuginfo = Some(v.clone()); + } + if let Some(v) = profile.rpath { self.rpath = Some(v); } diff --git a/src/doc/src/reference/profiles.md b/src/doc/src/reference/profiles.md index c8692f38c7e..d3c3d16cf97 100644 --- a/src/doc/src/reference/profiles.md +++ b/src/doc/src/reference/profiles.md @@ -71,8 +71,26 @@ The valid options are: * `1`: line tables only * `2` or `true`: full debug info +You may wish to also configure the [`split-debuginfo`](#split-debuginfo) option +depending on your needs as well. + [`-C debuginfo` flag]: ../../rustc/codegen-options/index.html#debuginfo +#### split-debuginfo + +The `split-debuginfo` setting controls the [`-C split-debuginfo` flag] which +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]. This option is currently not +passed by default on platforms other than macOS, where it defaults to +`unpacked`. The default may change in the future for platforms using DWARF +debugging information and ELF executables to `unpacked` as well once it is +stabilized in the compiler. + +[`-C split-debuginfo` flag]: ../../rustc/codegen-options/index.html#split-debuginfo + #### debug-assertions The `debug-assertions` setting controls the [`-C debug-assertions` flag] which diff --git a/tests/testsuite/build.rs b/tests/testsuite/build.rs index cbbcf46cb91..31b778a592c 100644 --- a/tests/testsuite/build.rs +++ b/tests/testsuite/build.rs @@ -4444,7 +4444,9 @@ fn uplift_dsym_of_bin_on_mac() { .file("tests/d.rs", "fn main() { panic!(); }") .build(); - p.cargo("build --bins --examples --tests").run(); + p.cargo("build --bins --examples --tests") + .enable_mac_dsym() + .run(); assert!(p.target_debug_dir().join("foo.dSYM").is_dir()); assert!(p.target_debug_dir().join("b.dSYM").is_dir()); assert!(p.target_debug_dir().join("b.dSYM").is_symlink()); @@ -4461,7 +4463,7 @@ fn uplift_dsym_of_bin_on_mac_when_broken_link_exists() { .build(); let dsym = p.target_debug_dir().join("foo.dSYM"); - p.cargo("build").run(); + p.cargo("build").enable_mac_dsym().run(); assert!(dsym.is_dir()); // Simulate the situation where the underlying dSYM bundle goes missing @@ -4477,7 +4479,7 @@ fn uplift_dsym_of_bin_on_mac_when_broken_link_exists() { assert!(dsym.is_symlink()); assert!(!dsym.exists()); - p.cargo("build").run(); + p.cargo("build").enable_mac_dsym().run(); assert!(dsym.is_dir()); } diff --git a/tests/testsuite/out_dir.rs b/tests/testsuite/out_dir.rs index f77db3785e2..300245fe864 100644 --- a/tests/testsuite/out_dir.rs +++ b/tests/testsuite/out_dir.rs @@ -14,6 +14,7 @@ fn binary_with_debug() { p.cargo("build -Z unstable-options --out-dir out") .masquerade_as_nightly_cargo() + .enable_mac_dsym() .run(); check_dir_contents( &p.root().join("out"), @@ -86,6 +87,7 @@ fn dynamic_library_with_debug() { p.cargo("build -Z unstable-options --out-dir out") .masquerade_as_nightly_cargo() + .enable_mac_dsym() .run(); check_dir_contents( &p.root().join("out"), @@ -165,6 +167,7 @@ fn include_only_the_binary_from_the_current_package() { p.cargo("build -Z unstable-options --bin foo --out-dir out") .masquerade_as_nightly_cargo() + .enable_mac_dsym() .run(); check_dir_contents( &p.root().join("out"), @@ -239,6 +242,7 @@ fn avoid_build_scripts() { p.cargo("build -Z unstable-options --out-dir out -vv") .masquerade_as_nightly_cargo() + .enable_mac_dsym() .with_stdout_contains("[a 0.0.1] hello-build-a") .with_stdout_contains("[b 0.0.1] hello-build-b") .run(); @@ -266,6 +270,7 @@ fn cargo_build_out_dir() { p.cargo("build -Z unstable-options") .masquerade_as_nightly_cargo() + .enable_mac_dsym() .run(); check_dir_contents( &p.root().join("out"), diff --git a/tests/testsuite/profile_config.rs b/tests/testsuite/profile_config.rs index 0bafe49db65..437c85cd460 100644 --- a/tests/testsuite/profile_config.rs +++ b/tests/testsuite/profile_config.rs @@ -233,7 +233,7 @@ fn profile_config_all_options() { [RUNNING] `rustc --crate-name foo [..] \ -C opt-level=1 \ -C panic=abort \ - -C lto \ + -C lto[..]\ -C codegen-units=2 \ -C debuginfo=2 \ -C debug-assertions=on \ @@ -342,64 +342,63 @@ 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::CompileKind; use cargo::core::compiler::CompileMode; use cargo::core::enable_nightly_features; - use cargo::core::features::Features; use cargo::core::profiles::{Profiles, UnitFor}; - use cargo::core::PackageId; + use cargo::core::{PackageId, Workspace}; use cargo::util::interning::InternedString; - use cargo::util::toml::TomlProfiles; use std::fs; enable_nightly_features(); paths::root().join(".cargo").mkdir_p(); fs::write( paths::root().join(".cargo/config"), r#" - [profile.foo] - inherits = "middle" - codegen-units = 2 - [profile.foo.build-override] - codegen-units = 6 - [profile.foo.package.dep] - codegen-units = 7 - - [profile.middle] - inherits = "bar" - codegen-units = 3 - - [profile.bar] - inherits = "dev" - codegen-units = 4 - debug = 1 + [profile.foo] + inherits = "middle" + codegen-units = 2 + [profile.foo.build-override] + codegen-units = 6 + [profile.foo.package.dep] + codegen-units = 7 + + [profile.middle] + inherits = "bar" + codegen-units = 3 + + [profile.bar] + inherits = "dev" + codegen-units = 4 + debug = 1 + "#, + ) + .unwrap(); + fs::write( + paths::root().join("Cargo.toml"), + r#" + cargo-features = ['named-profiles'] + + [workspace] + + [profile.middle] + inherits = "bar" + codegen-units = 1 + opt-level = 1 + [profile.middle.package.dep] + overflow-checks = false + + [profile.foo.build-override] + codegen-units = 5 + debug-assertions = false + [profile.foo.package.dep] + codegen-units = 8 "#, ) .unwrap(); let config = ConfigBuilder::new().build(); - let mut warnings = Vec::new(); - let features = Features::new(&["named-profiles".to_string()], &mut warnings).unwrap(); - assert_eq!(warnings.len(), 0); let profile_name = InternedString::new("foo"); - let toml = r#" - [profile.middle] - inherits = "bar" - codegen-units = 1 - opt-level = 1 - [profile.middle.package.dep] - overflow-checks = false - - [profile.foo.build-override] - codegen-units = 5 - debug-assertions = false - [profile.foo.package.dep] - codegen-units = 8 - "#; - #[derive(serde::Deserialize)] - struct TomlManifest { - profile: Option, - } - let manifest: TomlManifest = toml::from_str(toml).unwrap(); - let profiles = - Profiles::new(manifest.profile.as_ref(), &config, profile_name, &features).unwrap(); + let ws = Workspace::new(&paths::root().join("Cargo.toml"), &config).unwrap(); + let profiles = Profiles::new(&ws, profile_name).unwrap(); let crates_io = cargo::core::source::SourceId::crates_io(&config).unwrap(); let a_pkg = PackageId::new("a", "0.1.0", crates_io).unwrap(); @@ -407,7 +406,14 @@ fn named_config_profile() { // normal package let mode = CompileMode::Build; - let p = profiles.get_profile(a_pkg, true, true, UnitFor::new_normal(), mode); + let p = profiles.get_profile( + a_pkg, + true, + true, + UnitFor::new_normal(), + mode, + CompileKind::Host, + ); assert_eq!(p.name, "foo"); assert_eq!(p.codegen_units, Some(2)); // "foo" from config assert_eq!(p.opt_level, "1"); // "middle" from manifest @@ -416,7 +422,14 @@ 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, + CompileKind::Host, + ); 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 @@ -425,7 +438,14 @@ 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, + CompileKind::Host, + ); 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 diff --git a/tests/testsuite/rustc_info_cache.rs b/tests/testsuite/rustc_info_cache.rs index 24e3e075c66..26a06072199 100644 --- a/tests/testsuite/rustc_info_cache.rs +++ b/tests/testsuite/rustc_info_cache.rs @@ -6,6 +6,11 @@ use std::env; #[cargo_test] fn rustc_info_cache() { + // Currently detects a flag only supported on nightly. All other channels + // always have a miss. + if !cargo_test_support::is_nightly() { + return; + } let p = project() .file("src/main.rs", r#"fn main() { println!("hello"); }"#) .build(); diff --git a/tests/testsuite/unit_graph.rs b/tests/testsuite/unit_graph.rs index 257546b4f5e..977d04915c5 100644 --- a/tests/testsuite/unit_graph.rs +++ b/tests/testsuite/unit_graph.rs @@ -78,7 +78,8 @@ fn simple() { "rpath": false, "incremental": false, "panic": "unwind", - "strip": "none" + "strip": "none", + "split_debuginfo": "{...}" }, "platform": null, "mode": "build", @@ -121,7 +122,8 @@ fn simple() { "rpath": false, "incremental": false, "panic": "unwind", - "strip": "none" + "strip": "none", + "split_debuginfo": "{...}" }, "platform": null, "mode": "build", @@ -164,7 +166,8 @@ fn simple() { "rpath": false, "incremental": false, "panic": "unwind", - "strip": "none" + "strip": "none", + "split_debuginfo": "{...}" }, "platform": null, "mode": "build", @@ -200,7 +203,8 @@ fn simple() { "rpath": false, "incremental": false, "panic": "unwind", - "strip": "none" + "strip": "none", + "split_debuginfo": "{...}" }, "platform": null, "mode": "build", From cc5e9df64a7ed6b3657e9dd790e2e34387d33df5 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Mon, 1 Feb 2021 10:39:36 -0800 Subject: [PATCH 2/3] Cache failures in the rustc info cache This commit updates the rustc info cache to cache failures to execute rustc as well as successes. This fixes a weird issue where if you're probing for flags the `rustc_info_cache` test fails on channels which don't have the flag since previously a failure to execute rustc resulted in never caching the result. --- crates/cargo-test-support/src/lib.rs | 116 +++++++++++---------------- src/bin/cargo/commands/bench.rs | 2 +- src/bin/cargo/commands/run.rs | 3 +- src/bin/cargo/commands/test.rs | 2 +- src/bin/cargo/main.rs | 2 +- src/cargo/core/compiler/mod.rs | 2 +- src/cargo/util/errors.rs | 67 ++++++++++++---- src/cargo/util/mod.rs | 2 +- src/cargo/util/rustc.rs | 76 +++++++++++++----- tests/testsuite/rustc_info_cache.rs | 5 -- 10 files changed, 157 insertions(+), 120 deletions(-) diff --git a/crates/cargo-test-support/src/lib.rs b/crates/cargo-test-support/src/lib.rs index f12f935fa78..fbaa9dd0d9b 100644 --- a/crates/cargo-test-support/src/lib.rs +++ b/crates/cargo-test-support/src/lib.rs @@ -798,13 +798,17 @@ impl Execs { match res { Ok(out) => self.match_output(&out), Err(e) => { - let err = e.downcast_ref::(); - if let Some(&ProcessError { - output: Some(ref out), + if let Some(ProcessError { + stdout: Some(stdout), + stderr: Some(stderr), + code, .. - }) = err + }) = e.downcast_ref::() { - return self.match_output(out); + return self + .match_status(*code, stdout, stderr) + .and(self.match_stdout(stdout, stderr)) + .and(self.match_stderr(stdout, stderr)); } Err(format!("could not exec process {}: {:?}", process, e)) } @@ -813,119 +817,91 @@ impl Execs { fn match_output(&self, actual: &Output) -> MatchResult { self.verify_checks_output(actual); - self.match_status(actual) - .and(self.match_stdout(actual)) - .and(self.match_stderr(actual)) + self.match_status(actual.status.code(), &actual.stdout, &actual.stderr) + .and(self.match_stdout(&actual.stdout, &actual.stderr)) + .and(self.match_stderr(&actual.stdout, &actual.stderr)) } - fn match_status(&self, actual: &Output) -> MatchResult { + fn match_status(&self, code: Option, stdout: &[u8], stderr: &[u8]) -> MatchResult { match self.expect_exit_code { None => Ok(()), - Some(code) if actual.status.code() == Some(code) => Ok(()), + Some(expected) if code == Some(expected) => Ok(()), Some(_) => Err(format!( - "exited with {}\n--- stdout\n{}\n--- stderr\n{}", - actual.status, - String::from_utf8_lossy(&actual.stdout), - String::from_utf8_lossy(&actual.stderr) + "exited with {:?}\n--- stdout\n{}\n--- stderr\n{}", + code, + String::from_utf8_lossy(&stdout), + String::from_utf8_lossy(&stderr) )), } } - fn match_stdout(&self, actual: &Output) -> MatchResult { + fn match_stdout(&self, stdout: &[u8], stderr: &[u8]) -> MatchResult { self.match_std( self.expect_stdout.as_ref(), - &actual.stdout, + stdout, "stdout", - &actual.stderr, + stderr, MatchKind::Exact, )?; for expect in self.expect_stdout_contains.iter() { - self.match_std( - Some(expect), - &actual.stdout, - "stdout", - &actual.stderr, - MatchKind::Partial, - )?; + self.match_std(Some(expect), stdout, "stdout", stderr, MatchKind::Partial)?; } for expect in self.expect_stderr_contains.iter() { - self.match_std( - Some(expect), - &actual.stderr, - "stderr", - &actual.stdout, - MatchKind::Partial, - )?; + self.match_std(Some(expect), stderr, "stderr", stdout, MatchKind::Partial)?; } for &(ref expect, number) in self.expect_stdout_contains_n.iter() { self.match_std( Some(expect), - &actual.stdout, + stdout, "stdout", - &actual.stderr, + stderr, MatchKind::PartialN(number), )?; } for expect in self.expect_stdout_not_contains.iter() { self.match_std( Some(expect), - &actual.stdout, + stdout, "stdout", - &actual.stderr, + stderr, MatchKind::NotPresent, )?; } for expect in self.expect_stderr_not_contains.iter() { self.match_std( Some(expect), - &actual.stderr, + stderr, "stderr", - &actual.stdout, + stdout, MatchKind::NotPresent, )?; } for expect in self.expect_stderr_unordered.iter() { - self.match_std( - Some(expect), - &actual.stderr, - "stderr", - &actual.stdout, - MatchKind::Unordered, - )?; + self.match_std(Some(expect), stderr, "stderr", stdout, MatchKind::Unordered)?; } for expect in self.expect_neither_contains.iter() { self.match_std( Some(expect), - &actual.stdout, + stdout, "stdout", - &actual.stdout, + stdout, MatchKind::NotPresent, )?; self.match_std( Some(expect), - &actual.stderr, + stderr, "stderr", - &actual.stderr, + stderr, MatchKind::NotPresent, )?; } for expect in self.expect_either_contains.iter() { - let match_std = self.match_std( - Some(expect), - &actual.stdout, - "stdout", - &actual.stdout, - MatchKind::Partial, - ); - let match_err = self.match_std( - Some(expect), - &actual.stderr, - "stderr", - &actual.stderr, - MatchKind::Partial, - ); + let match_std = + self.match_std(Some(expect), stdout, "stdout", stdout, MatchKind::Partial); + let match_err = + self.match_std(Some(expect), stderr, "stderr", stderr, MatchKind::Partial); if let (Err(_), Err(_)) = (match_std, match_err) { return Err(format!( @@ -938,12 +914,12 @@ impl Execs { } for (with, without) in self.expect_stderr_with_without.iter() { - self.match_with_without(&actual.stderr, with, without)?; + self.match_with_without(stderr, with, without)?; } if let Some(ref objects) = self.expect_json { - let stdout = str::from_utf8(&actual.stdout) - .map_err(|_| "stdout was not utf8 encoded".to_owned())?; + let stdout = + str::from_utf8(stdout).map_err(|_| "stdout was not utf8 encoded".to_owned())?; let lines = stdout .lines() .filter(|line| line.starts_with('{')) @@ -962,8 +938,8 @@ impl Execs { } if !self.expect_json_contains_unordered.is_empty() { - let stdout = str::from_utf8(&actual.stdout) - .map_err(|_| "stdout was not utf8 encoded".to_owned())?; + let stdout = + str::from_utf8(stdout).map_err(|_| "stdout was not utf8 encoded".to_owned())?; let mut lines = stdout .lines() .filter(|line| line.starts_with('{')) @@ -990,12 +966,12 @@ impl Execs { Ok(()) } - fn match_stderr(&self, actual: &Output) -> MatchResult { + fn match_stderr(&self, stdout: &[u8], stderr: &[u8]) -> MatchResult { self.match_std( self.expect_stderr.as_ref(), - &actual.stderr, + stderr, "stderr", - &actual.stdout, + stdout, MatchKind::Exact, ) } diff --git a/src/bin/cargo/commands/bench.rs b/src/bin/cargo/commands/bench.rs index 160ccd9abe8..79580862e1f 100644 --- a/src/bin/cargo/commands/bench.rs +++ b/src/bin/cargo/commands/bench.rs @@ -74,7 +74,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { let err = ops::run_benches(&ws, &ops, &bench_args)?; match err { None => Ok(()), - Some(err) => Err(match err.exit.as_ref().and_then(|e| e.code()) { + Some(err) => Err(match err.code { Some(i) => CliError::new(anyhow::format_err!("bench failed"), i), None => CliError::new(err.into(), 101), }), diff --git a/src/bin/cargo/commands/run.rs b/src/bin/cargo/commands/run.rs index ed17e952b31..c8b711364d0 100644 --- a/src/bin/cargo/commands/run.rs +++ b/src/bin/cargo/commands/run.rs @@ -90,7 +90,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { // If we never actually spawned the process then that sounds pretty // bad and we always want to forward that up. - let exit = match proc_err.exit { + let exit_code = match proc_err.code { Some(exit) => exit, None => return CliError::new(err, 101), }; @@ -98,7 +98,6 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { // If `-q` was passed then we suppress extra error information about // a failed process, we assume the process itself printed out enough // information about why it failed so we don't do so as well - let exit_code = exit.code().unwrap_or(101); let is_quiet = config.shell().verbosity() == Verbosity::Quiet; if is_quiet { CliError::code(exit_code) diff --git a/src/bin/cargo/commands/test.rs b/src/bin/cargo/commands/test.rs index 04d4dce34fb..7e87afc8dcb 100644 --- a/src/bin/cargo/commands/test.rs +++ b/src/bin/cargo/commands/test.rs @@ -125,7 +125,7 @@ pub fn exec(config: &mut Config, args: &ArgMatches<'_>) -> CliResult { None => Ok(()), Some(err) => { let context = anyhow::format_err!("{}", err.hint(&ws, &ops.compile_opts)); - let e = match err.exit.as_ref().and_then(|e| e.code()) { + let e = match err.code { // Don't show "process didn't exit successfully" for simple errors. Some(i) if errors::is_simple_exit_code(i) => CliError::new(context, i), Some(i) => CliError::new(Error::from(err).context(context), i), diff --git a/src/bin/cargo/main.rs b/src/bin/cargo/main.rs index 64a465108a1..85b45a360ea 100644 --- a/src/bin/cargo/main.rs +++ b/src/bin/cargo/main.rs @@ -171,7 +171,7 @@ fn execute_external_subcommand(config: &Config, cmd: &str, args: &[&str]) -> Cli }; if let Some(perr) = err.downcast_ref::() { - if let Some(code) = perr.exit.as_ref().and_then(|c| c.code()) { + if let Some(code) = perr.code { return Err(CliError::code(code)); } } diff --git a/src/cargo/core/compiler/mod.rs b/src/cargo/core/compiler/mod.rs index d2cd60b2c79..23c3f384f05 100644 --- a/src/cargo/core/compiler/mod.rs +++ b/src/cargo/core/compiler/mod.rs @@ -297,7 +297,7 @@ fn rustc(cx: &mut Context<'_, '_>, unit: &Unit, exec: &Arc) -> Car match err .downcast_ref::() .as_ref() - .and_then(|perr| perr.exit.and_then(|e| e.code())) + .and_then(|perr| perr.code) { Some(n) if errors::is_simple_exit_code(n) => VerboseError::new(err).into(), _ => err, diff --git a/src/cargo/util/errors.rs b/src/cargo/util/errors.rs index acc301a5587..cf4ceb4bfdb 100644 --- a/src/cargo/util/errors.rs +++ b/src/cargo/util/errors.rs @@ -192,14 +192,25 @@ impl<'a> ::std::iter::FusedIterator for ManifestCauses<'a> {} pub struct ProcessError { /// A detailed description to show to the user why the process failed. pub desc: String, + /// The exit status of the process. /// - /// This can be `None` if the process failed to launch (like process not found). - pub exit: Option, - /// The output from the process. + /// This can be `None` if the process failed to launch (like process not + /// found) or if the exit status wasn't a code but was instead something + /// like termination via a signal. + pub code: Option, + + /// The stdout from the process. + /// + /// This can be `None` if the process failed to launch, or the output was + /// not captured. + pub stdout: Option>, + + /// The stderr from the process. /// - /// This can be `None` if the process failed to launch, or the output was not captured. - pub output: Option, + /// This can be `None` if the process failed to launch, or the output was + /// not captured. + pub stderr: Option>, } impl fmt::Display for ProcessError { @@ -218,7 +229,7 @@ impl std::error::Error for ProcessError {} pub struct CargoTestError { pub test: Test, pub desc: String, - pub exit: Option, + pub code: Option, pub causes: Vec, } @@ -254,7 +265,7 @@ impl CargoTestError { CargoTestError { test, desc, - exit: errors[0].exit, + code: errors[0].code, causes: errors, } } @@ -359,20 +370,39 @@ pub fn process_error( output: Option<&Output>, ) -> ProcessError { let exit = match status { - Some(s) => status_to_string(s), + Some(s) => exit_status_to_string(s), None => "never executed".to_string(), }; - let mut desc = format!("{} ({})", &msg, exit); - if let Some(out) = output { - match str::from_utf8(&out.stdout) { + process_error_raw( + msg, + status.and_then(|s| s.code()), + &exit, + output.map(|s| s.stdout.as_slice()), + output.map(|s| s.stderr.as_slice()), + ) +} + +pub fn process_error_raw( + msg: &str, + code: Option, + status: &str, + stdout: Option<&[u8]>, + stderr: Option<&[u8]>, +) -> ProcessError { + let mut desc = format!("{} ({})", msg, status); + + if let Some(out) = stdout { + match str::from_utf8(out) { Ok(s) if !s.trim().is_empty() => { desc.push_str("\n--- stdout\n"); desc.push_str(s); } Ok(..) | Err(..) => {} } - match str::from_utf8(&out.stderr) { + } + if let Some(out) = stderr { + match str::from_utf8(out) { Ok(s) if !s.trim().is_empty() => { desc.push_str("\n--- stderr\n"); desc.push_str(s); @@ -381,11 +411,16 @@ pub fn process_error( } } - return ProcessError { + ProcessError { desc, - exit: status, - output: output.cloned(), - }; + code, + stdout: stdout.map(|s| s.to_vec()), + stderr: stderr.map(|s| s.to_vec()), + } +} + +pub fn exit_status_to_string(status: ExitStatus) -> String { + return status_to_string(status); #[cfg(unix)] fn status_to_string(status: ExitStatus) -> String { diff --git a/src/cargo/util/mod.rs b/src/cargo/util/mod.rs index b9ca5797fa2..f0408d2a920 100644 --- a/src/cargo/util/mod.rs +++ b/src/cargo/util/mod.rs @@ -4,7 +4,7 @@ pub use self::canonical_url::CanonicalUrl; pub use self::config::{homedir, Config, ConfigValue}; pub use self::dependency_queue::DependencyQueue; pub use self::diagnostic_server::RustfixDiagnosticServer; -pub use self::errors::{internal, process_error}; +pub use self::errors::{exit_status_to_string, internal, process_error, process_error_raw}; pub use self::errors::{CargoResult, CargoResultExt, CliResult, Test}; pub use self::errors::{CargoTestError, CliError, ProcessError}; pub use self::flock::{FileLock, Filesystem}; diff --git a/src/cargo/util/rustc.rs b/src/cargo/util/rustc.rs index aa713818563..a0fc2df6c94 100644 --- a/src/cargo/util/rustc.rs +++ b/src/cargo/util/rustc.rs @@ -1,4 +1,4 @@ -use std::collections::hash_map::{Entry, HashMap}; +use std::collections::hash_map::HashMap; use std::env; use std::hash::{Hash, Hasher}; use std::path::{Path, PathBuf}; @@ -123,10 +123,19 @@ struct Cache { #[derive(Serialize, Deserialize, Debug, Default)] struct CacheData { rustc_fingerprint: u64, - outputs: HashMap, + outputs: HashMap, successes: HashMap, } +#[derive(Serialize, Deserialize, Debug)] +struct Output { + success: bool, + status: String, + code: Option, + stdout: String, + stderr: String, +} + impl Cache { fn load(rustc: &Path, rustup_rustc: &Path, cache_location: Option) -> Cache { match (cache_location, rustc_fingerprint(rustc, rustup_rustc)) { @@ -180,26 +189,49 @@ impl Cache { fn cached_output(&mut self, cmd: &ProcessBuilder) -> CargoResult<(String, String)> { let key = process_fingerprint(cmd); - match self.data.outputs.entry(key) { - Entry::Occupied(entry) => { - debug!("rustc info cache hit"); - Ok(entry.get().clone()) - } - Entry::Vacant(entry) => { - debug!("rustc info cache miss"); - debug!("running {}", cmd); - let output = cmd.exec_with_output()?; - let stdout = String::from_utf8(output.stdout) - .map_err(|e| anyhow::anyhow!("{}: {:?}", e, e.as_bytes())) - .chain_err(|| anyhow::anyhow!("`{}` didn't return utf8 output", cmd))?; - let stderr = String::from_utf8(output.stderr) - .map_err(|e| anyhow::anyhow!("{}: {:?}", e, e.as_bytes())) - .chain_err(|| anyhow::anyhow!("`{}` didn't return utf8 output", cmd))?; - let output = (stdout, stderr); - entry.insert(output.clone()); - self.dirty = true; - Ok(output) - } + if self.data.outputs.contains_key(&key) { + debug!("rustc info cache hit"); + } else { + debug!("rustc info cache miss"); + debug!("running {}", cmd); + let output = cmd + .build_command() + .output() + .chain_err(|| format!("could not execute process {} (never executed)", cmd))?; + let stdout = String::from_utf8(output.stdout) + .map_err(|e| anyhow::anyhow!("{}: {:?}", e, e.as_bytes())) + .chain_err(|| anyhow::anyhow!("`{}` didn't return utf8 output", cmd))?; + let stderr = String::from_utf8(output.stderr) + .map_err(|e| anyhow::anyhow!("{}: {:?}", e, e.as_bytes())) + .chain_err(|| anyhow::anyhow!("`{}` didn't return utf8 output", cmd))?; + self.data.outputs.insert( + key, + Output { + success: output.status.success(), + status: if output.status.success() { + String::new() + } else { + util::exit_status_to_string(output.status) + }, + code: output.status.code(), + stdout, + stderr, + }, + ); + self.dirty = true; + } + let output = &self.data.outputs[&key]; + if output.success { + Ok((output.stdout.clone(), output.stderr.clone())) + } else { + Err(util::process_error_raw( + &format!("process didn't exit successfully: {}", cmd), + output.code, + &output.status, + Some(output.stdout.as_ref()), + Some(output.stderr.as_ref()), + ) + .into()) } } } diff --git a/tests/testsuite/rustc_info_cache.rs b/tests/testsuite/rustc_info_cache.rs index 26a06072199..24e3e075c66 100644 --- a/tests/testsuite/rustc_info_cache.rs +++ b/tests/testsuite/rustc_info_cache.rs @@ -6,11 +6,6 @@ use std::env; #[cargo_test] fn rustc_info_cache() { - // Currently detects a flag only supported on nightly. All other channels - // always have a miss. - if !cargo_test_support::is_nightly() { - return; - } let p = project() .file("src/main.rs", r#"fn main() { println!("hello"); }"#) .build(); From ffa9dbd34853457fd07f5c7152dc03adee069c96 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 2 Feb 2021 13:38:12 -0800 Subject: [PATCH 3/3] Don't change the macOS default just yet --- src/cargo/core/compiler/standard_lib.rs | 15 +++++------ src/cargo/core/compiler/unit_dependencies.rs | 1 - src/cargo/core/profiles.rs | 20 +------------- src/cargo/ops/cargo_compile.rs | 15 +++++------ tests/testsuite/profile_config.rs | 28 +++----------------- 5 files changed, 18 insertions(+), 61 deletions(-) diff --git a/src/cargo/core/compiler/standard_lib.rs b/src/cargo/core/compiler/standard_lib.rs index 67d6189304b..0b14df8055a 100644 --- a/src/cargo/core/compiler/standard_lib.rs +++ b/src/cargo/core/compiler/standard_lib.rs @@ -162,17 +162,16 @@ 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 profile = profiles.get_profile( - pkg.package_id(), - /*is_member*/ false, - /*is_local*/ false, - unit_for, - mode, - *kind, - ); let list = ret.entry(*kind).or_insert_with(Vec::new); list.push(interner.intern( pkg, diff --git a/src/cargo/core/compiler/unit_dependencies.rs b/src/cargo/core/compiler/unit_dependencies.rs index 22c29c66f34..9445bb8861e 100644 --- a/src/cargo/core/compiler/unit_dependencies.rs +++ b/src/cargo/core/compiler/unit_dependencies.rs @@ -593,7 +593,6 @@ fn new_unit_dep( is_local, unit_for, mode, - kind, ); new_unit_dep_with_profile(state, parent, pkg, target, unit_for, kind, mode, profile) } diff --git a/src/cargo/core/profiles.rs b/src/cargo/core/profiles.rs index b65832407ba..dcc4011e81d 100644 --- a/src/cargo/core/profiles.rs +++ b/src/cargo/core/profiles.rs @@ -1,4 +1,4 @@ -use crate::core::compiler::{CompileKind, CompileMode, Unit}; +use crate::core::compiler::{CompileMode, Unit}; use crate::core::resolver::features::FeaturesFor; use crate::core::{Feature, PackageId, PackageIdSpec, Resolve, Shell, Target, Workspace}; use crate::util::errors::CargoResultExt; @@ -291,7 +291,6 @@ 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 @@ -347,23 +346,6 @@ impl Profiles { } } - // Default macOS debug information to being stored in the "packed" - // 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; diff --git a/src/cargo/ops/cargo_compile.rs b/src/cargo/ops/cargo_compile.rs index 2a32ad7b2f7..b14bb5d690f 100644 --- a/src/cargo/ops/cargo_compile.rs +++ b/src/cargo/ops/cargo_compile.rs @@ -882,20 +882,19 @@ 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.for_target(target), - ); let unit = interner.intern( pkg, target, diff --git a/tests/testsuite/profile_config.rs b/tests/testsuite/profile_config.rs index 437c85cd460..2449e5a171e 100644 --- a/tests/testsuite/profile_config.rs +++ b/tests/testsuite/profile_config.rs @@ -342,7 +342,6 @@ 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::CompileKind; use cargo::core::compiler::CompileMode; use cargo::core::enable_nightly_features; use cargo::core::profiles::{Profiles, UnitFor}; @@ -406,14 +405,7 @@ fn named_config_profile() { // normal package let mode = CompileMode::Build; - let p = profiles.get_profile( - a_pkg, - true, - true, - UnitFor::new_normal(), - mode, - CompileKind::Host, - ); + let p = profiles.get_profile(a_pkg, true, true, UnitFor::new_normal(), mode); assert_eq!(p.name, "foo"); assert_eq!(p.codegen_units, Some(2)); // "foo" from config assert_eq!(p.opt_level, "1"); // "middle" from manifest @@ -422,14 +414,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, - CompileKind::Host, - ); + let bo = profiles.get_profile(a_pkg, true, true, UnitFor::new_host(false), mode); 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 @@ -438,14 +423,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, - CompileKind::Host, - ); + let po = profiles.get_profile(dep_pkg, false, true, UnitFor::new_normal(), mode); 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