@@ -357,11 +357,20 @@ final class PackagePIFProjectBuilder: PIFProjectBuilder {
357
357
addBuildConfiguration ( name: " Release " , settings: releaseSettings)
358
358
359
359
for product in package . products. sorted ( by: { $0. name < $1. name } ) {
360
- try self . addTarget ( for: product)
360
+ let productScope = observabilityScope. makeChildScope (
361
+ description: " Adding \( product. name) product " ,
362
+ metadata: package . underlying. diagnosticsMetadata
363
+ )
364
+
365
+ productScope. trap { try self . addTarget ( for: product) }
361
366
}
362
367
363
368
for target in package . targets. sorted ( by: { $0. name < $1. name } ) {
364
- try self . addTarget ( for: target)
369
+ let targetScope = observabilityScope. makeChildScope (
370
+ description: " Adding \( target. name) module " ,
371
+ metadata: package . underlying. diagnosticsMetadata
372
+ )
373
+ targetScope. trap { try self . addTarget ( for: target) }
365
374
}
366
375
367
376
if self . binaryGroup. children. isEmpty {
@@ -485,10 +494,7 @@ final class PackagePIFProjectBuilder: PIFProjectBuilder {
485
494
settings [ . GCC_C_LANGUAGE_STANDARD] = clangTarget. cLanguageStandard
486
495
settings [ . CLANG_CXX_LANGUAGE_STANDARD] = clangTarget. cxxLanguageStandard
487
496
} else if let swiftTarget = mainTarget. underlying as? SwiftTarget {
488
- settings [ . SWIFT_VERSION] = try swiftTarget
489
- . computeEffectiveSwiftVersion ( supportedSwiftVersions: self . parameters. supportedSwiftVersions)
490
- . description
491
-
497
+ try settings. addSwiftVersionSettings ( target: swiftTarget, parameters: self . parameters)
492
498
settings. addCommonSwiftSettings ( package : self . package , target: mainTarget, parameters: self . parameters)
493
499
}
494
500
@@ -676,9 +682,8 @@ final class PackagePIFProjectBuilder: PIFProjectBuilder {
676
682
shouldImpartModuleMap = false
677
683
}
678
684
} else if let swiftTarget = target. underlying as? SwiftTarget {
679
- settings [ . SWIFT_VERSION] = try swiftTarget
680
- . computeEffectiveSwiftVersion ( supportedSwiftVersions: self . parameters. supportedSwiftVersions)
681
- . description
685
+ try settings. addSwiftVersionSettings ( target: swiftTarget, parameters: self . parameters)
686
+
682
687
// Generate ObjC compatibility header for Swift library targets.
683
688
settings [ . SWIFT_OBJC_INTERFACE_HEADER_DIR] = " $(OBJROOT)/GeneratedModuleMaps/$(PLATFORM_NAME) "
684
689
settings [ . SWIFT_OBJC_INTERFACE_HEADER_NAME] = " \( target. name) -Swift.h "
@@ -1575,31 +1580,6 @@ extension Target {
1575
1580
}
1576
1581
}
1577
1582
1578
- extension SwiftTarget {
1579
- func computeEffectiveSwiftVersion( supportedSwiftVersions: [ SwiftLanguageVersion ] ) throws -> SwiftLanguageVersion {
1580
- // We have to normalize to two component strings to match the results from XCBuild w.r.t. to hashing of
1581
- // `SwiftLanguageVersion` instances.
1582
- let normalizedDeclaredVersions = Set ( self . declaredSwiftVersions. compactMap {
1583
- SwiftLanguageVersion ( string: " \( $0. major) . \( $0. minor) " )
1584
- } )
1585
- // If we were able to determine the list of versions supported by XCBuild, cross-reference with the package's
1586
- // Swift versions in case the preferred version isn't available.
1587
- if !supportedSwiftVersions. isEmpty, !supportedSwiftVersions. contains ( self . toolSwiftVersion) {
1588
- let declaredVersions = Array ( normalizedDeclaredVersions. intersection ( supportedSwiftVersions) ) . sorted ( by: > )
1589
- if let swiftVersion = declaredVersions. first {
1590
- return swiftVersion
1591
- } else {
1592
- throw PIFGenerationError . unsupportedSwiftLanguageVersion (
1593
- targetName: self . name,
1594
- version: self . toolSwiftVersion,
1595
- supportedVersions: supportedSwiftVersions
1596
- )
1597
- }
1598
- }
1599
- return self . toolSwiftVersion
1600
- }
1601
- }
1602
-
1603
1583
extension ProductType {
1604
1584
var targetType : Target . Kind {
1605
1585
switch self {
@@ -1828,6 +1808,93 @@ extension PIF.PlatformFilter {
1828
1808
}
1829
1809
1830
1810
extension PIF . BuildSettings {
1811
+ fileprivate mutating func addSwiftVersionSettings(
1812
+ target: SwiftTarget ,
1813
+ parameters: PIFBuilderParameters
1814
+ ) throws {
1815
+ guard let versionAssignments = target. buildSettings. assignments [ . SWIFT_VERSION] else {
1816
+ // This should never happens in practice because there is always a default tools version based value.
1817
+ return
1818
+ }
1819
+
1820
+ func isSupportedVersion( _ version: SwiftLanguageVersion ) -> Bool {
1821
+ parameters. supportedSwiftVersions. isEmpty || parameters. supportedSwiftVersions. contains ( version)
1822
+ }
1823
+
1824
+ func computeEffectiveSwiftVersions( for versions: [ SwiftLanguageVersion ] ) -> [ String ] {
1825
+ versions
1826
+ . filter { target. declaredSwiftVersions. contains ( $0) }
1827
+ . filter { isSupportedVersion ( $0) } . map ( \. description)
1828
+ }
1829
+
1830
+ func computeEffectiveTargetVersion( for assignment: BuildSettings . Assignment ) throws -> String {
1831
+ let versions = assignment. values. compactMap { SwiftLanguageVersion ( string: $0) }
1832
+ if let effectiveVersion = computeEffectiveSwiftVersions ( for: versions) . last {
1833
+ return effectiveVersion
1834
+ }
1835
+
1836
+ throw PIFGenerationError . unsupportedSwiftLanguageVersions (
1837
+ targetName: target. name,
1838
+ versions: versions,
1839
+ supportedVersions: parameters. supportedSwiftVersions
1840
+ )
1841
+ }
1842
+
1843
+ var toolsSwiftVersion : SwiftLanguageVersion ? = nil
1844
+ // First, check whether there are any target specific settings.
1845
+ for assignment in versionAssignments {
1846
+ if assignment. default {
1847
+ toolsSwiftVersion = assignment. values. first. flatMap { . init( string: $0) }
1848
+ continue
1849
+ }
1850
+
1851
+ if assignment. conditions. isEmpty {
1852
+ self [ . SWIFT_VERSION] = try computeEffectiveTargetVersion ( for: assignment)
1853
+ continue
1854
+ }
1855
+
1856
+ for condition in assignment. conditions {
1857
+ if let platforms = condition. platformsCondition {
1858
+ for platform : Platform in platforms. platforms. compactMap ( { . init( rawValue: $0. name) } ) {
1859
+ self [ . SWIFT_VERSION, for: platform] = try computeEffectiveTargetVersion ( for: assignment)
1860
+ }
1861
+ }
1862
+ }
1863
+ }
1864
+
1865
+ // If there were no target specific assignments, let's add a fallback tools version based value.
1866
+ if let toolsSwiftVersion, self [ . SWIFT_VERSION] == nil {
1867
+ // Use tools based version if it's supported.
1868
+ if isSupportedVersion ( toolsSwiftVersion) {
1869
+ self [ . SWIFT_VERSION] = toolsSwiftVersion. description
1870
+ return
1871
+ }
1872
+
1873
+ // Otherwise pick the newest supported tools version based value.
1874
+
1875
+ // We have to normalize to two component strings to match the results from XCBuild w.r.t. to hashing of
1876
+ // `SwiftLanguageVersion` instances.
1877
+ let normalizedDeclaredVersions = Set ( target. declaredSwiftVersions. compactMap {
1878
+ SwiftLanguageVersion ( string: " \( $0. major) . \( $0. minor) " )
1879
+ } )
1880
+
1881
+ let declaredSwiftVersions = Array (
1882
+ normalizedDeclaredVersions
1883
+ . intersection ( parameters. supportedSwiftVersions)
1884
+ ) . sorted ( by: > )
1885
+ if let swiftVersion = declaredSwiftVersions. first {
1886
+ self [ . SWIFT_VERSION] = swiftVersion. description
1887
+ return
1888
+ }
1889
+
1890
+ throw PIFGenerationError . unsupportedSwiftLanguageVersions (
1891
+ targetName: target. name,
1892
+ versions: Array ( normalizedDeclaredVersions) ,
1893
+ supportedVersions: parameters. supportedSwiftVersions
1894
+ )
1895
+ }
1896
+ }
1897
+
1831
1898
fileprivate mutating func addCommonSwiftSettings(
1832
1899
package : ResolvedPackage ,
1833
1900
target: ResolvedModule ,
@@ -1859,9 +1926,22 @@ extension PIF.BuildSettings.Platform {
1859
1926
}
1860
1927
1861
1928
public enum PIFGenerationError : Error {
1862
- case unsupportedSwiftLanguageVersion (
1929
+ case unsupportedSwiftLanguageVersions (
1863
1930
targetName: String ,
1864
- version : SwiftLanguageVersion ,
1931
+ versions : [ SwiftLanguageVersion ] ,
1865
1932
supportedVersions: [ SwiftLanguageVersion ]
1866
1933
)
1867
1934
}
1935
+
1936
+ extension PIFGenerationError : CustomStringConvertible {
1937
+ public var description : String {
1938
+ switch self {
1939
+ case . unsupportedSwiftLanguageVersions(
1940
+ targetName: let target,
1941
+ versions: let given,
1942
+ supportedVersions: let supported
1943
+ ) :
1944
+ " Some of the Swift language versions used in target ' \( target) ' settings are supported. (given: \( given) , supported: \( supported) ) "
1945
+ }
1946
+ }
1947
+ }
0 commit comments