1- use crate :: core:: compiler:: { CompileMode , Unit } ;
1+ use crate :: core:: compiler:: { CompileKind , CompileMode , Unit } ;
22use crate :: core:: resolver:: features:: FeaturesFor ;
3- use crate :: core:: { Feature , Features , PackageId , PackageIdSpec , Resolve , Shell , Target } ;
3+ use crate :: core:: { Feature , PackageId , PackageIdSpec , Resolve , Shell , Target , Workspace } ;
44use crate :: util:: errors:: CargoResultExt ;
55use crate :: util:: interning:: InternedString ;
66use crate :: util:: toml:: { ProfilePackageSpec , StringOrBool , TomlProfile , TomlProfiles , U32OrBool } ;
77use crate :: util:: { closest_msg, config, CargoResult , Config } ;
88use anyhow:: bail;
99use std:: collections:: { BTreeMap , HashMap , HashSet } ;
10+ use std:: hash:: Hash ;
1011use std:: { cmp, env, fmt, hash} ;
1112
1213/// Collection of all profiles.
@@ -24,28 +25,28 @@ pub struct Profiles {
2425 named_profiles_enabled : bool ,
2526 /// The profile the user requested to use.
2627 requested_profile : InternedString ,
28+ /// The host target for rustc being used by this `Profiles`.
29+ rustc_host : InternedString ,
2730}
2831
2932impl Profiles {
30- pub fn new (
31- profiles : Option < & TomlProfiles > ,
32- config : & Config ,
33- requested_profile : InternedString ,
34- features : & Features ,
35- ) -> CargoResult < Profiles > {
33+ pub fn new ( ws : & Workspace < ' _ > , requested_profile : InternedString ) -> CargoResult < Profiles > {
34+ let config = ws. config ( ) ;
3635 let incremental = match env:: var_os ( "CARGO_INCREMENTAL" ) {
3736 Some ( v) => Some ( v == "1" ) ,
3837 None => config. build_config ( ) ?. incremental ,
3938 } ;
40- let mut profiles = merge_config_profiles ( profiles, config, requested_profile, features) ?;
39+ let mut profiles = merge_config_profiles ( ws, requested_profile) ?;
40+ let rustc_host = ws. config ( ) . load_global_rustc ( Some ( ws) ) ?. host ;
4141
42- if !features . is_enabled ( Feature :: named_profiles ( ) ) {
42+ if !ws . unstable_features ( ) . is_enabled ( Feature :: named_profiles ( ) ) {
4343 let mut profile_makers = Profiles {
4444 incremental,
4545 named_profiles_enabled : false ,
4646 dir_names : Self :: predefined_dir_names ( ) ,
4747 by_name : HashMap :: new ( ) ,
4848 requested_profile,
49+ rustc_host,
4950 } ;
5051
5152 profile_makers. by_name . insert (
@@ -98,6 +99,7 @@ impl Profiles {
9899 dir_names : Self :: predefined_dir_names ( ) ,
99100 by_name : HashMap :: new ( ) ,
100101 requested_profile,
102+ rustc_host,
101103 } ;
102104
103105 Self :: add_root_profiles ( & mut profile_makers, & profiles) ;
@@ -289,6 +291,7 @@ impl Profiles {
289291 is_local : bool ,
290292 unit_for : UnitFor ,
291293 mode : CompileMode ,
294+ kind : CompileKind ,
292295 ) -> Profile {
293296 let ( profile_name, inherits) = if !self . named_profiles_enabled {
294297 // With the feature disabled, we degrade `--profile` back to the
@@ -344,10 +347,28 @@ impl Profiles {
344347 }
345348 }
346349
350+ // Default macOS debug information to being stored in the "packed"
351+ // split-debuginfo format. At the time of this writing that's the only
352+ // platform which has a stable `-Csplit-debuginfo` option for rustc,
353+ // and it's typically much faster than running `dsymutil` on all builds
354+ // in incremental cases.
355+ if let Some ( debug) = profile. debuginfo {
356+ if profile. split_debuginfo . is_none ( ) && debug > 0 {
357+ let target = match & kind {
358+ CompileKind :: Host => self . rustc_host . as_str ( ) ,
359+ CompileKind :: Target ( target) => target. short_name ( ) ,
360+ } ;
361+ if target. contains ( "-apple-" ) {
362+ profile. split_debuginfo = Some ( InternedString :: new ( "unpacked" ) ) ;
363+ }
364+ }
365+ }
366+
347367 // Incremental can be globally overridden.
348368 if let Some ( v) = self . incremental {
349369 profile. incremental = v;
350370 }
371+
351372 // Only enable incremental compilation for sources the user can
352373 // modify (aka path sources). For things that change infrequently,
353374 // non-incremental builds yield better performance in the compiler
@@ -567,6 +588,9 @@ fn merge_profile(profile: &mut Profile, toml: &TomlProfile) {
567588 if let Some ( debug_assertions) = toml. debug_assertions {
568589 profile. debug_assertions = debug_assertions;
569590 }
591+ if let Some ( split_debuginfo) = & toml. split_debuginfo {
592+ profile. split_debuginfo = Some ( InternedString :: new ( split_debuginfo) ) ;
593+ }
570594 if let Some ( rpath) = toml. rpath {
571595 profile. rpath = rpath;
572596 }
@@ -612,6 +636,7 @@ pub struct Profile {
612636 // `None` means use rustc default.
613637 pub codegen_units : Option < u32 > ,
614638 pub debuginfo : Option < u32 > ,
639+ pub split_debuginfo : Option < InternedString > ,
615640 pub debug_assertions : bool ,
616641 pub overflow_checks : bool ,
617642 pub rpath : bool ,
@@ -630,6 +655,7 @@ impl Default for Profile {
630655 codegen_units : None ,
631656 debuginfo : None ,
632657 debug_assertions : false ,
658+ split_debuginfo : None ,
633659 overflow_checks : false ,
634660 rpath : false ,
635661 incremental : false ,
@@ -654,6 +680,7 @@ compact_debug! {
654680 root
655681 codegen_units
656682 debuginfo
683+ split_debuginfo
657684 debug_assertions
658685 overflow_checks
659686 rpath
@@ -734,25 +761,13 @@ impl Profile {
734761 /// Compares all fields except `name`, which doesn't affect compilation.
735762 /// This is necessary for `Unit` deduplication for things like "test" and
736763 /// "dev" which are essentially the same.
737- fn comparable (
738- & self ,
739- ) -> (
740- InternedString ,
741- Lto ,
742- Option < u32 > ,
743- Option < u32 > ,
744- bool ,
745- bool ,
746- bool ,
747- bool ,
748- PanicStrategy ,
749- Strip ,
750- ) {
764+ fn comparable ( & self ) -> impl Hash + Eq {
751765 (
752766 self . opt_level ,
753767 self . lto ,
754768 self . codegen_units ,
755769 self . debuginfo ,
770+ self . split_debuginfo ,
756771 self . debug_assertions ,
757772 self . overflow_checks ,
758773 self . rpath ,
@@ -1073,12 +1088,10 @@ impl UnitFor {
10731088///
10741089/// Returns a new copy of the profile map with all the mergers complete.
10751090fn merge_config_profiles (
1076- profiles : Option < & TomlProfiles > ,
1077- config : & Config ,
1091+ ws : & Workspace < ' _ > ,
10781092 requested_profile : InternedString ,
1079- features : & Features ,
10801093) -> CargoResult < BTreeMap < InternedString , TomlProfile > > {
1081- let mut profiles = match profiles {
1094+ let mut profiles = match ws . profiles ( ) {
10821095 Some ( profiles) => profiles. get_all ( ) . clone ( ) ,
10831096 None => BTreeMap :: new ( ) ,
10841097 } ;
@@ -1087,7 +1100,7 @@ fn merge_config_profiles(
10871100 check_to_add. insert ( requested_profile) ;
10881101 // Merge config onto manifest profiles.
10891102 for ( name, profile) in & mut profiles {
1090- if let Some ( config_profile) = get_config_profile ( name , config , features ) ? {
1103+ if let Some ( config_profile) = get_config_profile ( ws , name ) ? {
10911104 profile. merge ( & config_profile) ;
10921105 }
10931106 if let Some ( inherits) = & profile. inherits {
@@ -1106,7 +1119,7 @@ fn merge_config_profiles(
11061119 std:: mem:: swap ( & mut current, & mut check_to_add) ;
11071120 for name in current. drain ( ) {
11081121 if !profiles. contains_key ( & name) {
1109- if let Some ( config_profile) = get_config_profile ( & name , config , features ) ? {
1122+ if let Some ( config_profile) = get_config_profile ( ws , & name ) ? {
11101123 if let Some ( inherits) = & config_profile. inherits {
11111124 check_to_add. insert ( * inherits) ;
11121125 }
@@ -1119,20 +1132,17 @@ fn merge_config_profiles(
11191132}
11201133
11211134/// Helper for fetching a profile from config.
1122- fn get_config_profile (
1123- name : & str ,
1124- config : & Config ,
1125- features : & Features ,
1126- ) -> CargoResult < Option < TomlProfile > > {
1127- let profile: Option < config:: Value < TomlProfile > > = config. get ( & format ! ( "profile.{}" , name) ) ?;
1135+ fn get_config_profile ( ws : & Workspace < ' _ > , name : & str ) -> CargoResult < Option < TomlProfile > > {
1136+ let profile: Option < config:: Value < TomlProfile > > =
1137+ ws. config ( ) . get ( & format ! ( "profile.{}" , name) ) ?;
11281138 let profile = match profile {
11291139 Some ( profile) => profile,
11301140 None => return Ok ( None ) ,
11311141 } ;
11321142 let mut warnings = Vec :: new ( ) ;
11331143 profile
11341144 . val
1135- . validate ( name, features , & mut warnings)
1145+ . validate ( name, ws . unstable_features ( ) , & mut warnings)
11361146 . chain_err ( || {
11371147 anyhow:: format_err!(
11381148 "config profile `{}` is not valid (defined in `{}`)" ,
@@ -1141,7 +1151,7 @@ fn get_config_profile(
11411151 )
11421152 } ) ?;
11431153 for warning in warnings {
1144- config. shell ( ) . warn ( warning) ?;
1154+ ws . config ( ) . shell ( ) . warn ( warning) ?;
11451155 }
11461156 Ok ( Some ( profile. val ) )
11471157}
0 commit comments