@@ -524,14 +524,93 @@ extension PackageGraph.ResolvedModule {
524
524
}
525
525
526
526
struct AllBuildSettings {
527
- typealias BuildSettingsByPlatform =
528
- [ ProjectModel . BuildSettings . Platform ? : [ BuildSettings . Declaration : [ String ] ] ]
527
+ typealias SingleValueSettingsByPlatform =
528
+ [ ProjectModel . BuildSettings . Platform ? : [ ProjectModel . BuildSettings . SingleValueSetting : String ] ]
529
+ typealias MultipleValueSettingsByPlatform =
530
+ [ ProjectModel . BuildSettings . Platform ? : [ ProjectModel . BuildSettings . MultipleValueSetting : [ String ] ] ]
529
531
530
- /// Target-specific build settings declared in the manifest and that apply to the target itself.
531
- var targetSettings : [ BuildConfiguration : BuildSettingsByPlatform ] = [ : ]
532
+ /// Target-specific single-value build settings declared in the manifest and that apply to the target itself.
533
+ var targetSingleValueSettings : [ BuildConfiguration : SingleValueSettingsByPlatform ] = [ : ]
534
+
535
+ /// Target-specific multiple-value build settings declared in the manifest and that apply to the target itself.
536
+ var targetMultipleValueSettings : [ BuildConfiguration : MultipleValueSettingsByPlatform ] = [ : ]
532
537
533
- /// Target-specific build settings that should be imparted to client targets (packages and projects).
534
- var impartedSettings : BuildSettingsByPlatform = [ : ]
538
+ /// Target-specific single-value build settings that should be imparted to client targets (packages and projects).
539
+ var impartedSingleValueSettings : SingleValueSettingsByPlatform = [ : ]
540
+
541
+ /// Target-specific multiple-value build settings that should be imparted to client targets (packages and projects).
542
+ var impartedMultipleValueSettings : MultipleValueSettingsByPlatform = [ : ]
543
+
544
+ // MARK: - Convenience Methods
545
+
546
+ /// Apply all settings to a ProjectModel.BuildSettings instance
547
+ func apply( to buildSettings: inout ProjectModel . BuildSettings , for configuration: BuildConfiguration ) {
548
+ // Apply single value settings for all platforms
549
+ if let singleValuesByPlatform = targetSingleValueSettings [ configuration] {
550
+ for (platform, singleValues) in singleValuesByPlatform {
551
+ for (setting, value) in singleValues {
552
+ if let platform = platform {
553
+ buildSettings [ setting, platform] = value
554
+ } else {
555
+ buildSettings [ setting] = value
556
+ }
557
+ }
558
+ }
559
+ }
560
+
561
+ // Apply multiple value settings for all platforms
562
+ if let multipleValuesByPlatform = targetMultipleValueSettings [ configuration] {
563
+ // First, collect all multiple-value settings that are being used
564
+ var usedMultipleValueSettings = Set < ProjectModel . BuildSettings . MultipleValueSetting > ( )
565
+ for (_, multipleValues) in multipleValuesByPlatform {
566
+ for (setting, _) in multipleValues {
567
+ usedMultipleValueSettings. insert ( setting)
568
+ }
569
+ }
570
+
571
+ // Now apply the platform-specific values
572
+ for (platform, multipleValues) in multipleValuesByPlatform {
573
+ for (setting, values) in multipleValues {
574
+ if let platform = platform {
575
+ // Get existing values (should now be initialized with inherited)
576
+ let existingValues = buildSettings [ setting, platform] ?? [ " $(inherited) " ]
577
+ buildSettings [ setting, platform] = existingValues + values
578
+ } else {
579
+ // Append to existing values instead of overwriting
580
+ let existingValues = buildSettings [ setting] ?? [ " $(inherited) " ]
581
+ buildSettings [ setting] = existingValues + values
582
+ }
583
+ }
584
+ }
585
+ }
586
+ }
587
+
588
+ /// Apply imparted settings to a ProjectModel.BuildSettings instance
589
+ func applyImparted( to buildSettings: inout ProjectModel . BuildSettings ) {
590
+ // Apply imparted single value settings for all platforms
591
+ for (platform, singleValues) in impartedSingleValueSettings {
592
+ for (setting, value) in singleValues {
593
+ if let platform = platform {
594
+ buildSettings [ setting, platform] = value
595
+ } else {
596
+ buildSettings [ setting] = value
597
+ }
598
+ }
599
+ }
600
+
601
+ // Apply imparted multiple value settings for all platforms
602
+ for (platform, multipleValues) in impartedMultipleValueSettings {
603
+ for (setting, values) in multipleValues {
604
+ if let platform = platform {
605
+ let existingValues = buildSettings [ setting, platform] ?? [ " $(inherited) " ]
606
+ buildSettings [ setting, platform] = existingValues + values
607
+ } else {
608
+ let existingValues = buildSettings [ setting] ?? [ " $(inherited) " ]
609
+ buildSettings [ setting] = existingValues + values
610
+ }
611
+ }
612
+ }
613
+ }
535
614
}
536
615
537
616
/// Target-specific build settings declared in the manifest and that apply to the target itself.
@@ -546,20 +625,31 @@ extension PackageGraph.ResolvedModule {
546
625
for settingAssignment in settingsAssigments {
547
626
// Create a build setting value; in some cases there
548
627
// isn't a direct mapping to Swift Build build settings.
549
- let pifDeclaration : BuildSettings . Declaration
550
628
let values : [ String ]
629
+ let singleValueSetting : ProjectModel . BuildSettings . SingleValueSetting ?
630
+ let multipleValueSetting : ProjectModel . BuildSettings . MultipleValueSetting ?
631
+
551
632
switch declaration {
552
633
case . LINK_FRAMEWORKS:
553
- pifDeclaration = . OTHER_LDFLAGS
634
+ singleValueSetting = nil
635
+ multipleValueSetting = . OTHER_LDFLAGS
554
636
values = settingAssignment. values. flatMap { [ " -framework " , $0] }
555
637
case . LINK_LIBRARIES:
556
- pifDeclaration = . OTHER_LDFLAGS
638
+ singleValueSetting = nil
639
+ multipleValueSetting = . OTHER_LDFLAGS
557
640
values = settingAssignment. values. map { " -l \( $0) " }
558
641
case . HEADER_SEARCH_PATHS:
559
- pifDeclaration = . HEADER_SEARCH_PATHS
642
+ singleValueSetting = nil
643
+ multipleValueSetting = . HEADER_SEARCH_PATHS
560
644
values = settingAssignment. values. map { self . sourceDirAbsolutePath. pathString + " / " + $0 }
561
645
default :
562
- pifDeclaration = ProjectModel . BuildSettings. Declaration ( from: declaration)
646
+ if declaration. allowsMultipleValues {
647
+ singleValueSetting = nil
648
+ multipleValueSetting = ProjectModel . BuildSettings. MultipleValueSetting ( from: declaration)
649
+ } else {
650
+ singleValueSetting = ProjectModel . BuildSettings. SingleValueSetting ( from: declaration)
651
+ multipleValueSetting = nil
652
+ }
563
653
values = settingAssignment. values
564
654
}
565
655
@@ -578,26 +668,19 @@ extension PackageGraph.ResolvedModule {
578
668
pifPlatform = nil
579
669
}
580
670
581
- if pifDeclaration == . OTHER_LDFLAGS {
582
- var settingsByDeclaration : [ ProjectModel . BuildSettings . Declaration : [ String ] ]
583
-
584
- settingsByDeclaration = allSettings. impartedSettings [ pifPlatform] ?? [ : ]
585
- settingsByDeclaration [ pifDeclaration, default: [ ] ] . append ( contentsOf: values)
586
-
587
- allSettings. impartedSettings [ pifPlatform] = settingsByDeclaration
671
+ // Handle imparted settings for OTHER_LDFLAGS (always multiple values)
672
+ if let multipleValueSetting = multipleValueSetting, multipleValueSetting == . OTHER_LDFLAGS {
673
+ allSettings. impartedMultipleValueSettings [ pifPlatform, default: [ : ] ] [ multipleValueSetting, default: [ ] ] . append ( contentsOf: values)
588
674
}
589
675
590
676
for configuration in configurations {
591
- var settingsByDeclaration : [ ProjectModel . BuildSettings . Declaration : [ String ] ]
592
- settingsByDeclaration = allSettings. targetSettings [ configuration] ? [ pifPlatform] ?? [ : ]
593
-
594
- if declaration. allowsMultipleValues {
595
- settingsByDeclaration [ pifDeclaration, default: [ ] ] . append ( contentsOf: values)
596
- } else {
597
- settingsByDeclaration [ pifDeclaration] = values. only. flatMap { [ $0] } ?? [ ]
677
+ if let multipleValueSetting = multipleValueSetting {
678
+ // Handle multiple value settings
679
+ allSettings. targetMultipleValueSettings [ configuration, default: [ : ] ] [ pifPlatform, default: [ : ] ] [ multipleValueSetting, default: [ ] ] . append ( contentsOf: values)
680
+ } else if let singleValueSetting = singleValueSetting, let singleValue = values. only {
681
+ // Handle single value settings
682
+ allSettings. targetSingleValueSettings [ configuration, default: [ : ] ] [ pifPlatform, default: [ : ] ] [ singleValueSetting] = singleValue
598
683
}
599
-
600
- allSettings. targetSettings [ configuration, default: [ : ] ] [ pifPlatform] = settingsByDeclaration
601
684
}
602
685
}
603
686
}
@@ -911,88 +994,8 @@ extension ProjectModel.BuildSettings {
911
994
/// Note that this restricts the settings that can be set by this function to those that can have platform-specific
912
995
/// values, i.e. those in `ProjectModel.BuildSettings.Declaration`. If a platform is specified,
913
996
/// it must be one of the known platforms in `ProjectModel.BuildSettings.Platform`.
914
- mutating func append( values: [ String ] , to setting: Declaration , platform: Platform ? = nil ) {
915
- // This dichotomy is quite unfortunate but that's currently the underlying model in ProjectModel.BuildSettings.
916
- if let platform {
917
- switch setting {
918
- case . FRAMEWORK_SEARCH_PATHS,
919
- . GCC_PREPROCESSOR_DEFINITIONS,
920
- . HEADER_SEARCH_PATHS,
921
- . OTHER_CFLAGS,
922
- . OTHER_CPLUSPLUSFLAGS,
923
- . OTHER_LDFLAGS,
924
- . OTHER_SWIFT_FLAGS,
925
- . SWIFT_ACTIVE_COMPILATION_CONDITIONS:
926
- // Appending implies the setting is resilient to having ["$(inherited)"]
927
- self . platformSpecificSettings [ platform] ![ setting] !. append ( contentsOf: values)
928
-
929
- case . SWIFT_VERSION, . DYLIB_INSTALL_NAME_BASE:
930
- self . platformSpecificSettings [ platform] ![ setting] = values // We are not resilient to $(inherited).
931
-
932
- case . ARCHS, . IPHONEOS_DEPLOYMENT_TARGET, . SPECIALIZATION_SDK_OPTIONS:
933
- fatalError ( " Unexpected BuildSettings.Declaration: \( setting) " )
934
- // Allow staging in new cases
935
- default :
936
- fatalError ( " Unhandled enum case in BuildSettings.Declaration. Will generate a warning until we have SE-0487 " )
937
- }
938
- } else {
939
- switch setting {
940
- case . FRAMEWORK_SEARCH_PATHS,
941
- . GCC_PREPROCESSOR_DEFINITIONS,
942
- . HEADER_SEARCH_PATHS,
943
- . OTHER_CFLAGS,
944
- . OTHER_CPLUSPLUSFLAGS,
945
- . OTHER_LDFLAGS,
946
- . OTHER_SWIFT_FLAGS,
947
- . SWIFT_ACTIVE_COMPILATION_CONDITIONS:
948
- let multipleSetting = MultipleValueSetting ( from: setting) !
949
- self [ multipleSetting, default: [ " $(inherited) " ] ] . append ( contentsOf: values)
950
-
951
- case . SWIFT_VERSION:
952
- self [ . SWIFT_VERSION] = values. only. unwrap ( orAssert: " Invalid values for 'SWIFT_VERSION': \( values) " )
953
-
954
- case . DYLIB_INSTALL_NAME_BASE:
955
- self [ . DYLIB_INSTALL_NAME_BASE] = values. only. unwrap ( orAssert: " Invalid values for 'DYLIB_INSTALL_NAME_BASE': \( values) " )
956
-
957
- case . ARCHS, . IPHONEOS_DEPLOYMENT_TARGET, . SPECIALIZATION_SDK_OPTIONS:
958
- fatalError ( " Unexpected BuildSettings.Declaration: \( setting) " )
959
- // Allow staging in new cases
960
- default :
961
- fatalError ( " Unhandled enum case in BuildSettings.Declaration. Will generate a warning until we have SE-0487 " )
962
- }
963
- }
964
- }
965
997
}
966
998
967
- extension ProjectModel . BuildSettings . MultipleValueSetting {
968
- init ? ( from declaration: ProjectModel . BuildSettings . Declaration ) {
969
- switch declaration {
970
- case . GCC_PREPROCESSOR_DEFINITIONS:
971
- self = . GCC_PREPROCESSOR_DEFINITIONS
972
- case . FRAMEWORK_SEARCH_PATHS:
973
- self = . FRAMEWORK_SEARCH_PATHS
974
- case . HEADER_SEARCH_PATHS:
975
- self = . HEADER_SEARCH_PATHS
976
- case . OTHER_CFLAGS:
977
- self = . OTHER_CFLAGS
978
- case . OTHER_CPLUSPLUSFLAGS:
979
- self = . OTHER_CPLUSPLUSFLAGS
980
- case . OTHER_LDFLAGS:
981
- self = . OTHER_LDFLAGS
982
- case . OTHER_SWIFT_FLAGS:
983
- self = . OTHER_SWIFT_FLAGS
984
- case . SPECIALIZATION_SDK_OPTIONS:
985
- self = . SPECIALIZATION_SDK_OPTIONS
986
- case . SWIFT_ACTIVE_COMPILATION_CONDITIONS:
987
- self = . SWIFT_ACTIVE_COMPILATION_CONDITIONS
988
- case . ARCHS, . IPHONEOS_DEPLOYMENT_TARGET, . SWIFT_VERSION, . DYLIB_INSTALL_NAME_BASE:
989
- return nil
990
- // Allow staging in new cases
991
- default :
992
- fatalError ( " Unhandled enum case in BuildSettings.Declaration. Will generate a warning until we have SE-0487 " )
993
- }
994
- }
995
- }
996
999
997
1000
extension ProjectModel . BuildSettings . Platform {
998
1001
enum Error : Swift . Error {
@@ -1034,7 +1037,6 @@ extension ProjectModel.BuildSettings {
1034
1037
self [ . PRODUCT_NAME] = productName
1035
1038
self [ . PRODUCT_MODULE_NAME] = productName
1036
1039
self [ . PRODUCT_BUNDLE_IDENTIFIER] = " \( packageIdentity) . \( productName) " . spm_mangledToBundleIdentifier ( )
1037
- self [ . CLANG_ENABLE_MODULES] = " YES "
1038
1040
self [ . SWIFT_PACKAGE_NAME] = packageName ?? nil
1039
1041
1040
1042
if !createDylibForDynamicProducts {
@@ -1061,32 +1063,36 @@ extension ProjectModel.BuildSettings {
1061
1063
}
1062
1064
}
1063
1065
1064
- extension ProjectModel . BuildSettings . Declaration {
1065
- init ( from declaration: PackageModel . BuildSettings . Declaration ) {
1066
- self = switch declaration {
1067
- // Swift.
1066
+ extension ProjectModel . BuildSettings . SingleValueSetting {
1067
+ init ? ( from declaration: PackageModel . BuildSettings . Declaration ) {
1068
+ switch declaration {
1069
+ case . SWIFT_VERSION:
1070
+ self = . SWIFT_VERSION
1071
+ default :
1072
+ return nil
1073
+ }
1074
+ }
1075
+ }
1076
+
1077
+ extension ProjectModel . BuildSettings . MultipleValueSetting {
1078
+ init ? ( from declaration: PackageModel . BuildSettings . Declaration ) {
1079
+ switch declaration {
1068
1080
case . SWIFT_ACTIVE_COMPILATION_CONDITIONS:
1069
- . SWIFT_ACTIVE_COMPILATION_CONDITIONS
1081
+ self = . SWIFT_ACTIVE_COMPILATION_CONDITIONS
1070
1082
case . OTHER_SWIFT_FLAGS:
1071
- . OTHER_SWIFT_FLAGS
1072
- case . SWIFT_VERSION:
1073
- . SWIFT_VERSION
1074
- // C family.
1083
+ self = . OTHER_SWIFT_FLAGS
1075
1084
case . GCC_PREPROCESSOR_DEFINITIONS:
1076
- . GCC_PREPROCESSOR_DEFINITIONS
1085
+ self = . GCC_PREPROCESSOR_DEFINITIONS
1077
1086
case . HEADER_SEARCH_PATHS:
1078
- . HEADER_SEARCH_PATHS
1087
+ self = . HEADER_SEARCH_PATHS
1079
1088
case . OTHER_CFLAGS:
1080
- . OTHER_CFLAGS
1089
+ self = . OTHER_CFLAGS
1081
1090
case . OTHER_CPLUSPLUSFLAGS:
1082
- . OTHER_CPLUSPLUSFLAGS
1083
- // Linker.
1091
+ self = . OTHER_CPLUSPLUSFLAGS
1084
1092
case . OTHER_LDFLAGS:
1085
- . OTHER_LDFLAGS
1086
- case . LINK_LIBRARIES, . LINK_FRAMEWORKS:
1087
- preconditionFailure ( " Should not be reached " )
1093
+ self = . OTHER_LDFLAGS
1088
1094
default :
1089
- preconditionFailure ( " Unexpected BuildSettings.Declaration: \( declaration . name ) " )
1095
+ return nil
1090
1096
}
1091
1097
}
1092
1098
}
0 commit comments