@@ -524,6 +524,25 @@ public struct SwiftSDK: Equatable {
524
524
environment: Environment = . current,
525
525
observabilityScope: ObservabilityScope ? = nil ,
526
526
fileSystem: any FileSystem = localFileSystem
527
+ ) throws -> SwiftSDK {
528
+ try self . systemSwiftSDK (
529
+ binDir,
530
+ environment: environment,
531
+ observabilityScope: observabilityScope,
532
+ fileSystem: fileSystem
533
+ )
534
+ }
535
+
536
+ /// A default Swift SDK on the host.
537
+ ///
538
+ /// Equivalent to `hostSwiftSDK`, except on macOS, where passing a non-nil `darwinPlatformOverride`
539
+ /// will result in the SDK for the corresponding Darwin platform.
540
+ private static func systemSwiftSDK(
541
+ _ binDir: AbsolutePath ? = nil ,
542
+ environment: Environment = . current,
543
+ observabilityScope: ObservabilityScope ? = nil ,
544
+ fileSystem: any FileSystem = localFileSystem,
545
+ darwinPlatformOverride: DarwinPlatform ? = nil
527
546
) throws -> SwiftSDK {
528
547
// Select the correct binDir.
529
548
if environment [ " SWIFTPM_CUSTOM_BINDIR " ] != nil {
@@ -535,13 +554,16 @@ public struct SwiftSDK: Equatable {
535
554
536
555
let sdkPath : AbsolutePath ?
537
556
#if os(macOS)
557
+ let darwinPlatform = darwinPlatformOverride ?? . macOS
538
558
// Get the SDK.
539
559
if let value = environment [ " SDKROOT " ] {
540
560
sdkPath = try AbsolutePath ( validating: value)
561
+ } else if let value = environment [ EnvironmentKey ( " SWIFTPM_SDKROOT_ \( darwinPlatform. xcrunName) " ) ] {
562
+ sdkPath = try AbsolutePath ( validating: value)
541
563
} else {
542
564
// No value in env, so search for it.
543
565
let sdkPathStr = try AsyncProcess . checkNonZeroExit (
544
- arguments: [ " /usr/bin/xcrun " , " --sdk " , " macosx " , " --show-sdk-path " ] ,
566
+ arguments: [ " /usr/bin/xcrun " , " --sdk " , darwinPlatform . xcrunName , " --show-sdk-path " ] ,
545
567
environment: environment
546
568
) . spm_chomp ( )
547
569
guard !sdkPathStr. isEmpty else {
@@ -559,11 +581,11 @@ public struct SwiftSDK: Equatable {
559
581
var extraSwiftCFlags : [ String ] = [ ]
560
582
#if os(macOS)
561
583
do {
562
- let sdkPaths = try SwiftSDK . sdkPlatformFrameworkPaths ( environment: environment)
563
- extraCCFlags += [ " -F " , sdkPaths. fwk . pathString]
564
- extraSwiftCFlags += [ " -F " , sdkPaths. fwk . pathString]
565
- extraSwiftCFlags += [ " -I " , sdkPaths. lib . pathString]
566
- extraSwiftCFlags += [ " -L " , sdkPaths. lib . pathString]
584
+ let sdkPaths = try SwiftSDK . sdkPlatformPaths ( for : darwinPlatform , environment: environment)
585
+ extraCCFlags += [ " -F " , sdkPaths. frameworks . pathString]
586
+ extraSwiftCFlags += [ " -F " , sdkPaths. frameworks . pathString]
587
+ extraSwiftCFlags += [ " -I " , sdkPaths. libraries . pathString]
588
+ extraSwiftCFlags += [ " -L " , sdkPaths. libraries . pathString]
567
589
xctestSupport = . supported
568
590
} catch {
569
591
xctestSupport = . unsupported( reason: String ( describing: error) )
@@ -589,15 +611,40 @@ public struct SwiftSDK: Equatable {
589
611
)
590
612
}
591
613
614
+ /// Auxiliary platform frameworks and libraries.
615
+ ///
616
+ /// The referenced directories may contain, for example, test support utilities.
617
+ ///
618
+ /// - SeeAlso: ``sdkPlatformPaths(for:environment:)``
619
+ public struct PlatformPaths {
620
+ /// Path to the directory containing auxiliary platform frameworks.
621
+ public var frameworks : AbsolutePath
622
+
623
+ /// Path to the directory containing auxiliary platform libraries.
624
+ public var libraries : AbsolutePath
625
+ }
626
+
592
627
/// Returns `macosx` sdk platform framework path.
628
+ @available ( * , deprecated, message: " use sdkPlatformPaths(for:) instead " )
593
629
public static func sdkPlatformFrameworkPaths(
594
630
environment: Environment = . current
595
631
) throws -> ( fwk: AbsolutePath , lib: AbsolutePath ) {
596
- if let path = _sdkPlatformFrameworkPath {
632
+ let paths = try sdkPlatformPaths ( for: . macOS, environment: environment)
633
+ return ( fwk: paths. frameworks, lib: paths. libraries)
634
+ }
635
+
636
+ /// Returns ``SwiftSDK/PlatformPaths`` for the provided Darwin platform.
637
+ public static func sdkPlatformPaths(
638
+ for darwinPlatform: DarwinPlatform ,
639
+ environment: Environment = . current
640
+ ) throws -> PlatformPaths {
641
+ if let path = _sdkPlatformFrameworkPath [ darwinPlatform] {
597
642
return path
598
643
}
599
- let platformPath = try AsyncProcess . checkNonZeroExit (
600
- arguments: [ " /usr/bin/xcrun " , " --sdk " , " macosx " , " --show-sdk-platform-path " ] ,
644
+ let platformPath = try environment [
645
+ EnvironmentKey ( " SWIFTPM_PLATFORM_PATH_ \( darwinPlatform. xcrunName) " )
646
+ ] ?? AsyncProcess . checkNonZeroExit (
647
+ arguments: [ " /usr/bin/xcrun " , " --sdk " , darwinPlatform. xcrunName, " --show-sdk-platform-path " ] ,
601
648
environment: environment
602
649
) . spm_chomp ( )
603
650
@@ -615,33 +662,26 @@ public struct SwiftSDK: Equatable {
615
662
components: " Developer " , " usr " , " lib "
616
663
)
617
664
618
- let sdkPlatformFrameworkPath = ( fwk, lib)
619
- _sdkPlatformFrameworkPath = sdkPlatformFrameworkPath
665
+ let sdkPlatformFrameworkPath = PlatformPaths ( frameworks : fwk, libraries : lib)
666
+ _sdkPlatformFrameworkPath [ darwinPlatform ] = sdkPlatformFrameworkPath
620
667
return sdkPlatformFrameworkPath
621
668
}
622
669
623
- // FIXME: convert this from a tuple to a proper struct with documented properties
624
- /// Cache storage for sdk platform path.
625
- private static var _sdkPlatformFrameworkPath : ( fwk: AbsolutePath , lib: AbsolutePath ) ? = nil
670
+ /// Cache storage for sdk platform paths.
671
+ private static var _sdkPlatformFrameworkPath : [ DarwinPlatform : PlatformPaths ] = [ : ]
626
672
627
673
/// Returns a default Swift SDK for a given target environment
628
674
@available ( * , deprecated, renamed: " defaultSwiftSDK " )
629
675
public static func defaultDestination( for triple: Triple , host: SwiftSDK ) -> SwiftSDK ? {
630
- if triple. isWASI ( ) {
631
- let wasiSysroot = host. toolset. rootPaths. first?
632
- . parentDirectory // usr
633
- . appending ( components: " share " , " wasi-sysroot " )
634
- return SwiftSDK (
635
- targetTriple: triple,
636
- toolset: host. toolset,
637
- pathsConfiguration: . init( sdkRootPath: wasiSysroot)
638
- )
639
- }
640
- return nil
676
+ defaultSwiftSDK ( for: triple, hostSDK: host)
641
677
}
642
678
643
679
/// Returns a default Swift SDK of a given target environment.
644
- public static func defaultSwiftSDK( for targetTriple: Triple , hostSDK: SwiftSDK ) -> SwiftSDK ? {
680
+ public static func defaultSwiftSDK(
681
+ for targetTriple: Triple ,
682
+ hostSDK: SwiftSDK ,
683
+ environment: Environment = . current
684
+ ) -> SwiftSDK ? {
645
685
if targetTriple. isWASI ( ) {
646
686
let wasiSysroot = hostSDK. toolset. rootPaths. first?
647
687
. parentDirectory // usr
@@ -652,6 +692,20 @@ public struct SwiftSDK: Equatable {
652
692
pathsConfiguration: . init( sdkRootPath: wasiSysroot)
653
693
)
654
694
}
695
+
696
+ #if os(macOS)
697
+ if let darwinPlatform = targetTriple. darwinPlatform {
698
+ // the Darwin SDKs are trivially available on macOS
699
+ var sdk = try ? self . systemSwiftSDK (
700
+ hostSDK. toolset. rootPaths. first,
701
+ environment: environment,
702
+ darwinPlatformOverride: darwinPlatform
703
+ )
704
+ sdk? . targetTriple = targetTriple
705
+ return sdk
706
+ }
707
+ #endif
708
+
655
709
return nil
656
710
}
657
711
@@ -690,12 +744,23 @@ public struct SwiftSDK: Equatable {
690
744
} else {
691
745
throw SwiftSDKError . noSwiftSDKDecoded ( customDestination)
692
746
}
693
- } else if let triple = customCompileTriple,
694
- let targetSwiftSDK = SwiftSDK . defaultSwiftSDK ( for: triple , hostSDK: hostSwiftSDK)
747
+ } else if let targetTriple = customCompileTriple,
748
+ let targetSwiftSDK = SwiftSDK . defaultSwiftSDK ( for: targetTriple , hostSDK: hostSwiftSDK)
695
749
{
696
750
swiftSDK = targetSwiftSDK
697
751
} else if let swiftSDKSelector {
698
- swiftSDK = try store. selectBundle ( matching: swiftSDKSelector, hostTriple: hostTriple)
752
+ do {
753
+ swiftSDK = try store. selectBundle ( matching: swiftSDKSelector, hostTriple: hostTriple)
754
+ } catch {
755
+ // If a user-installed bundle for the selector doesn't exist, check if the
756
+ // selector is recognized as a default SDK.
757
+ if let targetTriple = try ? Triple ( swiftSDKSelector) ,
758
+ let defaultSDK = SwiftSDK . defaultSwiftSDK ( for: targetTriple, hostSDK: hostSwiftSDK) {
759
+ swiftSDK = defaultSDK
760
+ } else {
761
+ throw error
762
+ }
763
+ }
699
764
} else {
700
765
// Otherwise use the host toolchain.
701
766
swiftSDK = hostSwiftSDK
@@ -991,6 +1056,18 @@ extension SwiftSDK {
991
1056
}
992
1057
}
993
1058
1059
+ extension DarwinPlatform {
1060
+ /// The name xcrun uses to identify this platform.
1061
+ fileprivate var xcrunName : String {
1062
+ switch self {
1063
+ case . iOS( . catalyst) :
1064
+ return " macosx "
1065
+ default :
1066
+ return platformName
1067
+ }
1068
+ }
1069
+ }
1070
+
994
1071
/// Integer version of the schema of `destination.json` files used for cross-compilation.
995
1072
private struct VersionInfo : Codable {
996
1073
let version : Int
0 commit comments