@@ -530,14 +530,93 @@ extension PackageGraph.ResolvedModule {
530530 }
531531
532532 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 ] ] ]
535537
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 ] = [ : ]
538543
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+ }
541620 }
542621
543622 /// Target-specific build settings declared in the manifest and that apply to the target itself.
@@ -552,20 +631,31 @@ extension PackageGraph.ResolvedModule {
552631 for settingAssignment in settingsAssigments {
553632 // Create a build setting value; in some cases there
554633 // isn't a direct mapping to Swift Build build settings.
555- let pifDeclaration : BuildSettings . Declaration
556634 let values : [ String ]
635+ let singleValueSetting : ProjectModel . BuildSettings . SingleValueSetting ?
636+ let multipleValueSetting : ProjectModel . BuildSettings . MultipleValueSetting ?
637+
557638 switch declaration {
558639 case . LINK_FRAMEWORKS:
559- pifDeclaration = . OTHER_LDFLAGS
640+ singleValueSetting = nil
641+ multipleValueSetting = . OTHER_LDFLAGS
560642 values = settingAssignment. values. flatMap { [ " -framework " , $0] }
561643 case . LINK_LIBRARIES:
562- pifDeclaration = . OTHER_LDFLAGS
644+ singleValueSetting = nil
645+ multipleValueSetting = . OTHER_LDFLAGS
563646 values = settingAssignment. values. map { " -l \( $0) " }
564647 case . HEADER_SEARCH_PATHS:
565- pifDeclaration = . HEADER_SEARCH_PATHS
648+ singleValueSetting = nil
649+ multipleValueSetting = . HEADER_SEARCH_PATHS
566650 values = settingAssignment. values. map { self . sourceDirAbsolutePath. pathString + " / " + $0 }
567651 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+ }
569659 values = settingAssignment. values
570660 }
571661
@@ -584,26 +674,19 @@ extension PackageGraph.ResolvedModule {
584674 pifPlatform = nil
585675 }
586676
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)
594680 }
595681
596682 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
604689 }
605-
606- allSettings. targetSettings [ configuration, default: [ : ] ] [ pifPlatform] = settingsByDeclaration
607690 }
608691 }
609692 }
@@ -917,88 +1000,8 @@ extension ProjectModel.BuildSettings {
9171000 /// Note that this restricts the settings that can be set by this function to those that can have platform-specific
9181001 /// values, i.e. those in `ProjectModel.BuildSettings.Declaration`. If a platform is specified,
9191002 /// 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- }
9711003}
9721004
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- }
10021005
10031006extension ProjectModel . BuildSettings . Platform {
10041007 enum Error : Swift . Error {
@@ -1040,7 +1043,6 @@ extension ProjectModel.BuildSettings {
10401043 self [ . PRODUCT_NAME] = productName
10411044 self [ . PRODUCT_MODULE_NAME] = productName
10421045 self [ . PRODUCT_BUNDLE_IDENTIFIER] = " \( packageIdentity) . \( productName) " . spm_mangledToBundleIdentifier ( )
1043- self [ . CLANG_ENABLE_MODULES] = " YES "
10441046 self [ . SWIFT_PACKAGE_NAME] = packageName ?? nil
10451047
10461048 if !createDylibForDynamicProducts {
@@ -1067,32 +1069,36 @@ extension ProjectModel.BuildSettings {
10671069 }
10681070}
10691071
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 {
10741086 case . SWIFT_ACTIVE_COMPILATION_CONDITIONS:
1075- . SWIFT_ACTIVE_COMPILATION_CONDITIONS
1087+ self = . SWIFT_ACTIVE_COMPILATION_CONDITIONS
10761088 case . OTHER_SWIFT_FLAGS:
1077- . OTHER_SWIFT_FLAGS
1078- case . SWIFT_VERSION:
1079- . SWIFT_VERSION
1080- // C family.
1089+ self = . OTHER_SWIFT_FLAGS
10811090 case . GCC_PREPROCESSOR_DEFINITIONS:
1082- . GCC_PREPROCESSOR_DEFINITIONS
1091+ self = . GCC_PREPROCESSOR_DEFINITIONS
10831092 case . HEADER_SEARCH_PATHS:
1084- . HEADER_SEARCH_PATHS
1093+ self = . HEADER_SEARCH_PATHS
10851094 case . OTHER_CFLAGS:
1086- . OTHER_CFLAGS
1095+ self = . OTHER_CFLAGS
10871096 case . OTHER_CPLUSPLUSFLAGS:
1088- . OTHER_CPLUSPLUSFLAGS
1089- // Linker.
1097+ self = . OTHER_CPLUSPLUSFLAGS
10901098 case . OTHER_LDFLAGS:
1091- . OTHER_LDFLAGS
1092- case . LINK_LIBRARIES, . LINK_FRAMEWORKS:
1093- preconditionFailure ( " Should not be reached " )
1099+ self = . OTHER_LDFLAGS
10941100 default :
1095- preconditionFailure ( " Unexpected BuildSettings.Declaration: \( declaration . name ) " )
1101+ return nil
10961102 }
10971103 }
10981104}
0 commit comments