1
- use crate :: core:: compiler:: { CompileMode , Unit } ;
1
+ use crate :: core:: compiler:: { CompileKind , CompileMode , Unit } ;
2
2
use 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 } ;
4
4
use crate :: util:: errors:: CargoResultExt ;
5
5
use crate :: util:: interning:: InternedString ;
6
6
use crate :: util:: toml:: { ProfilePackageSpec , StringOrBool , TomlProfile , TomlProfiles , U32OrBool } ;
7
7
use crate :: util:: { closest_msg, config, CargoResult , Config } ;
8
8
use anyhow:: bail;
9
9
use std:: collections:: { BTreeMap , HashMap , HashSet } ;
10
+ use std:: hash:: Hash ;
10
11
use std:: { cmp, env, fmt, hash} ;
11
12
12
13
/// Collection of all profiles.
@@ -24,28 +25,28 @@ pub struct Profiles {
24
25
named_profiles_enabled : bool ,
25
26
/// The profile the user requested to use.
26
27
requested_profile : InternedString ,
28
+ /// The host target for rustc being used by this `Profiles`.
29
+ rustc_host : InternedString ,
27
30
}
28
31
29
32
impl 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 ( ) ;
36
35
let incremental = match env:: var_os ( "CARGO_INCREMENTAL" ) {
37
36
Some ( v) => Some ( v == "1" ) ,
38
37
None => config. build_config ( ) ?. incremental ,
39
38
} ;
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 ;
41
41
42
- if !features . is_enabled ( Feature :: named_profiles ( ) ) {
42
+ if !ws . unstable_features ( ) . is_enabled ( Feature :: named_profiles ( ) ) {
43
43
let mut profile_makers = Profiles {
44
44
incremental,
45
45
named_profiles_enabled : false ,
46
46
dir_names : Self :: predefined_dir_names ( ) ,
47
47
by_name : HashMap :: new ( ) ,
48
48
requested_profile,
49
+ rustc_host,
49
50
} ;
50
51
51
52
profile_makers. by_name . insert (
@@ -98,6 +99,7 @@ impl Profiles {
98
99
dir_names : Self :: predefined_dir_names ( ) ,
99
100
by_name : HashMap :: new ( ) ,
100
101
requested_profile,
102
+ rustc_host,
101
103
} ;
102
104
103
105
Self :: add_root_profiles ( & mut profile_makers, & profiles) ;
@@ -289,6 +291,7 @@ impl Profiles {
289
291
is_local : bool ,
290
292
unit_for : UnitFor ,
291
293
mode : CompileMode ,
294
+ kind : CompileKind ,
292
295
) -> Profile {
293
296
let ( profile_name, inherits) = if !self . named_profiles_enabled {
294
297
// With the feature disabled, we degrade `--profile` back to the
@@ -344,10 +347,28 @@ impl Profiles {
344
347
}
345
348
}
346
349
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
+
347
367
// Incremental can be globally overridden.
348
368
if let Some ( v) = self . incremental {
349
369
profile. incremental = v;
350
370
}
371
+
351
372
// Only enable incremental compilation for sources the user can
352
373
// modify (aka path sources). For things that change infrequently,
353
374
// non-incremental builds yield better performance in the compiler
@@ -567,6 +588,9 @@ fn merge_profile(profile: &mut Profile, toml: &TomlProfile) {
567
588
if let Some ( debug_assertions) = toml. debug_assertions {
568
589
profile. debug_assertions = debug_assertions;
569
590
}
591
+ if let Some ( split_debuginfo) = & toml. split_debuginfo {
592
+ profile. split_debuginfo = Some ( InternedString :: new ( split_debuginfo) ) ;
593
+ }
570
594
if let Some ( rpath) = toml. rpath {
571
595
profile. rpath = rpath;
572
596
}
@@ -612,6 +636,7 @@ pub struct Profile {
612
636
// `None` means use rustc default.
613
637
pub codegen_units : Option < u32 > ,
614
638
pub debuginfo : Option < u32 > ,
639
+ pub split_debuginfo : Option < InternedString > ,
615
640
pub debug_assertions : bool ,
616
641
pub overflow_checks : bool ,
617
642
pub rpath : bool ,
@@ -630,6 +655,7 @@ impl Default for Profile {
630
655
codegen_units : None ,
631
656
debuginfo : None ,
632
657
debug_assertions : false ,
658
+ split_debuginfo : None ,
633
659
overflow_checks : false ,
634
660
rpath : false ,
635
661
incremental : false ,
@@ -654,6 +680,7 @@ compact_debug! {
654
680
root
655
681
codegen_units
656
682
debuginfo
683
+ split_debuginfo
657
684
debug_assertions
658
685
overflow_checks
659
686
rpath
@@ -734,25 +761,13 @@ impl Profile {
734
761
/// Compares all fields except `name`, which doesn't affect compilation.
735
762
/// This is necessary for `Unit` deduplication for things like "test" and
736
763
/// "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 {
751
765
(
752
766
self . opt_level ,
753
767
self . lto ,
754
768
self . codegen_units ,
755
769
self . debuginfo ,
770
+ self . split_debuginfo ,
756
771
self . debug_assertions ,
757
772
self . overflow_checks ,
758
773
self . rpath ,
@@ -1073,12 +1088,10 @@ impl UnitFor {
1073
1088
///
1074
1089
/// Returns a new copy of the profile map with all the mergers complete.
1075
1090
fn merge_config_profiles (
1076
- profiles : Option < & TomlProfiles > ,
1077
- config : & Config ,
1091
+ ws : & Workspace < ' _ > ,
1078
1092
requested_profile : InternedString ,
1079
- features : & Features ,
1080
1093
) -> CargoResult < BTreeMap < InternedString , TomlProfile > > {
1081
- let mut profiles = match profiles {
1094
+ let mut profiles = match ws . profiles ( ) {
1082
1095
Some ( profiles) => profiles. get_all ( ) . clone ( ) ,
1083
1096
None => BTreeMap :: new ( ) ,
1084
1097
} ;
@@ -1087,7 +1100,7 @@ fn merge_config_profiles(
1087
1100
check_to_add. insert ( requested_profile) ;
1088
1101
// Merge config onto manifest profiles.
1089
1102
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 ) ? {
1091
1104
profile. merge ( & config_profile) ;
1092
1105
}
1093
1106
if let Some ( inherits) = & profile. inherits {
@@ -1106,7 +1119,7 @@ fn merge_config_profiles(
1106
1119
std:: mem:: swap ( & mut current, & mut check_to_add) ;
1107
1120
for name in current. drain ( ) {
1108
1121
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 ) ? {
1110
1123
if let Some ( inherits) = & config_profile. inherits {
1111
1124
check_to_add. insert ( * inherits) ;
1112
1125
}
@@ -1119,20 +1132,17 @@ fn merge_config_profiles(
1119
1132
}
1120
1133
1121
1134
/// 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) ) ?;
1128
1138
let profile = match profile {
1129
1139
Some ( profile) => profile,
1130
1140
None => return Ok ( None ) ,
1131
1141
} ;
1132
1142
let mut warnings = Vec :: new ( ) ;
1133
1143
profile
1134
1144
. val
1135
- . validate ( name, features , & mut warnings)
1145
+ . validate ( name, ws . unstable_features ( ) , & mut warnings)
1136
1146
. chain_err ( || {
1137
1147
anyhow:: format_err!(
1138
1148
"config profile `{}` is not valid (defined in `{}`)" ,
@@ -1141,7 +1151,7 @@ fn get_config_profile(
1141
1151
)
1142
1152
} ) ?;
1143
1153
for warning in warnings {
1144
- config. shell ( ) . warn ( warning) ?;
1154
+ ws . config ( ) . shell ( ) . warn ( warning) ?;
1145
1155
}
1146
1156
Ok ( Some ( profile. val ) )
1147
1157
}
0 commit comments