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