@@ -15,11 +15,44 @@ import SWBCore
1515import Foundation
1616
1717@PluginExtensionSystemActor public func initializePlugin( _ manager: PluginManager ) {
18+ let plugin = GenericUnixPlugin ( )
1819 manager. register ( GenericUnixDeveloperDirectoryExtension ( ) , type: DeveloperDirectoryExtensionPoint . self)
1920 manager. register ( GenericUnixPlatformSpecsExtension ( ) , type: SpecificationsExtensionPoint . self)
2021 manager. register ( GenericUnixPlatformInfoExtension ( ) , type: PlatformInfoExtensionPoint . self)
21- manager. register ( GenericUnixSDKRegistryExtension ( ) , type: SDKRegistryExtensionPoint . self)
22- manager. register ( GenericUnixToolchainRegistryExtension ( ) , type: ToolchainRegistryExtensionPoint . self)
22+ manager. register ( GenericUnixSDKRegistryExtension ( plugin: plugin) , type: SDKRegistryExtensionPoint . self)
23+ manager. register ( GenericUnixToolchainRegistryExtension ( plugin: plugin) , type: ToolchainRegistryExtensionPoint . self)
24+ }
25+
26+ final class GenericUnixPlugin : Sendable {
27+ func swiftExecutablePath( fs: any FSProxy ) -> Path ? {
28+ [
29+ Environment . current [ " SWIFT_EXEC " ] . map ( Path . init) ,
30+ StackedSearchPath ( environment: . current, fs: fs) . lookup ( Path ( " swift " ) )
31+ ] . compactMap { $0 } . first ( where: fs. exists)
32+ }
33+
34+ func swiftTargetInfo( swiftExecutablePath: Path ) async throws -> SwiftTargetInfo {
35+ let args = [ " -print-target-info " ]
36+ let executionResult = try await Process . getOutput ( url: URL ( fileURLWithPath: swiftExecutablePath. str) , arguments: args)
37+ guard executionResult. exitStatus. isSuccess else {
38+ throw RunProcessNonZeroExitError ( args: [ swiftExecutablePath. str] + args, workingDirectory: nil , environment: [ : ] , status: executionResult. exitStatus, stdout: ByteString ( executionResult. stdout) , stderr: ByteString ( executionResult. stderr) )
39+ }
40+ return try JSONDecoder ( ) . decode ( SwiftTargetInfo . self, from: executionResult. stdout)
41+ }
42+ }
43+
44+ struct SwiftTargetInfo : Decodable {
45+ struct TargetInfo : Decodable {
46+ let triple : LLVMTriple
47+ let unversionedTriple : LLVMTriple
48+ }
49+ let target : TargetInfo
50+ }
51+
52+ extension SwiftTargetInfo . TargetInfo {
53+ var tripleVersion : String ? {
54+ triple != unversionedTriple && triple. system. hasPrefix ( unversionedTriple. system) ? String ( triple. system. dropFirst ( unversionedTriple. system. count) ) . nilIfEmpty : nil
55+ }
2356}
2457
2558struct GenericUnixDeveloperDirectoryExtension : DeveloperDirectoryExtension {
@@ -69,9 +102,11 @@ struct GenericUnixPlatformInfoExtension: PlatformInfoExtension {
69102}
70103
71104struct GenericUnixSDKRegistryExtension : SDKRegistryExtension {
105+ let plugin : GenericUnixPlugin
106+
72107 func additionalSDKs( context: any SDKRegistryExtensionAdditionalSDKsContext ) async throws -> [ ( path: Path , platform: SWBCore . Platform ? , data: [ String : PropertyListItem ] ) ] {
73108 let operatingSystem = context. hostOperatingSystem
74- guard operatingSystem. createFallbackSystemToolchain, let platform = try context. platformRegistry. lookup ( name: operatingSystem. xcodePlatformName) else {
109+ guard operatingSystem. createFallbackSystemToolchain, let platform = try context. platformRegistry. lookup ( name: operatingSystem. xcodePlatformName) , let swift = plugin . swiftExecutablePath ( fs : context . fs ) else {
75110 return [ ]
76111 }
77112
@@ -100,6 +135,8 @@ struct GenericUnixSDKRegistryExtension: SDKRegistryExtension {
100135 tripleEnvironment = " "
101136 }
102137
138+ let swiftTargetInfo = try await plugin. swiftTargetInfo ( swiftExecutablePath: swift)
139+
103140 return try [ ( . root, platform, [
104141 " Type " : . plString( " SDK " ) ,
105142 " Version " : . plString( Version ( ProcessInfo . processInfo. operatingSystemVersion) . zeroTrimmed. description) ,
@@ -112,7 +149,7 @@ struct GenericUnixSDKRegistryExtension: SDKRegistryExtension {
112149 operatingSystem. xcodePlatformName: . plDict( [
113150 " Archs " : . plArray( [ . plString( Architecture . hostStringValue ?? " unknown " ) ] ) ,
114151 " LLVMTargetTripleEnvironment " : . plString( tripleEnvironment) ,
115- " LLVMTargetTripleSys " : . plString( operatingSystem. xcodePlatformName) ,
152+ " LLVMTargetTripleSys " : . plString( operatingSystem. xcodePlatformName + ( swiftTargetInfo . target . tripleVersion ?? " " ) ) ,
116153 " LLVMTargetTripleVendor " : . plString( " unknown " ) ,
117154 ] )
118155 ] ) ,
@@ -121,55 +158,47 @@ struct GenericUnixSDKRegistryExtension: SDKRegistryExtension {
121158}
122159
123160struct GenericUnixToolchainRegistryExtension : ToolchainRegistryExtension {
161+ let plugin : GenericUnixPlugin
162+
124163 func additionalToolchains( context: any ToolchainRegistryExtensionAdditionalToolchainsContext ) async throws -> [ Toolchain ] {
125164 let operatingSystem = context. hostOperatingSystem
126- guard operatingSystem. createFallbackSystemToolchain else {
165+ let fs = context. fs
166+ guard operatingSystem. createFallbackSystemToolchain, let swift = plugin. swiftExecutablePath ( fs: fs) else {
127167 return [ ]
128168 }
129169
130- let fs = context. fs
131-
132- for swift in [
133- Environment . current [ " SWIFT_EXEC " ] . map ( Path . init) ,
134- StackedSearchPath ( environment: . current, fs: fs) . lookup ( Path ( " swift " ) )
135- ] . compactMap ( \. self) {
136- if fs. exists ( swift) {
137- let realSwiftPath = try fs. realpath ( swift) . dirname. normalize ( )
138- let hasUsrBin = realSwiftPath. str. hasSuffix ( " /usr/bin " )
139- let hasUsrLocalBin = realSwiftPath. str. hasSuffix ( " /usr/local/bin " )
140- let path : Path
141- switch ( hasUsrBin, hasUsrLocalBin) {
142- case ( true , false ) :
143- path = realSwiftPath. dirname. dirname
144- case ( false , true ) :
145- path = realSwiftPath. dirname. dirname. dirname
146- case ( false , false ) :
147- throw StubError . error ( " Unexpected toolchain layout for Swift installation path: \( realSwiftPath) " )
148- case ( true , true ) :
149- preconditionFailure ( )
150- }
151- let llvmDirectories = try Array ( fs. listdir ( Path ( " /usr/lib " ) ) . filter { $0. hasPrefix ( " llvm- " ) } . sorted ( ) . reversed ( ) )
152- let llvmDirectoriesLocal = try Array ( fs. listdir ( Path ( " /usr/local " ) ) . filter { $0. hasPrefix ( " llvm " ) } . sorted ( ) . reversed ( ) )
153- return [
154- Toolchain (
155- identifier: ToolchainRegistry . defaultToolchainIdentifier,
156- displayName: " Default " ,
157- version: Version ( ) ,
158- aliases: [ " default " ] ,
159- path: path,
160- frameworkPaths: [ ] ,
161- libraryPaths: llvmDirectories. map { " /usr/lib/ \( $0) /lib " } + llvmDirectoriesLocal. map { " /usr/local/ \( $0) /lib " } + [ " /usr/lib64 " ] ,
162- defaultSettings: [ : ] ,
163- overrideSettings: [ : ] ,
164- defaultSettingsWhenPrimary: [ : ] ,
165- executableSearchPaths: realSwiftPath. dirname. relativeSubpath ( from: path) . map { [ path. join ( $0) . join ( " bin " ) ] } ?? [ ] ,
166- testingLibraryPlatformNames: [ ] ,
167- fs: fs)
168- ]
169- }
170+ let realSwiftPath = try fs. realpath ( swift) . dirname. normalize ( )
171+ let hasUsrBin = realSwiftPath. str. hasSuffix ( " /usr/bin " )
172+ let hasUsrLocalBin = realSwiftPath. str. hasSuffix ( " /usr/local/bin " )
173+ let path : Path
174+ switch ( hasUsrBin, hasUsrLocalBin) {
175+ case ( true , false ) :
176+ path = realSwiftPath. dirname. dirname
177+ case ( false , true ) :
178+ path = realSwiftPath. dirname. dirname. dirname
179+ case ( false , false ) :
180+ throw StubError . error ( " Unexpected toolchain layout for Swift installation path: \( realSwiftPath) " )
181+ case ( true , true ) :
182+ preconditionFailure ( )
170183 }
171-
172- return [ ]
184+ let llvmDirectories = try Array ( fs. listdir ( Path ( " /usr/lib " ) ) . filter { $0. hasPrefix ( " llvm- " ) } . sorted ( ) . reversed ( ) )
185+ let llvmDirectoriesLocal = try Array ( fs. listdir ( Path ( " /usr/local " ) ) . filter { $0. hasPrefix ( " llvm " ) } . sorted ( ) . reversed ( ) )
186+ return [
187+ Toolchain (
188+ identifier: ToolchainRegistry . defaultToolchainIdentifier,
189+ displayName: " Default " ,
190+ version: Version ( ) ,
191+ aliases: [ " default " ] ,
192+ path: path,
193+ frameworkPaths: [ ] ,
194+ libraryPaths: llvmDirectories. map { " /usr/lib/ \( $0) /lib " } + llvmDirectoriesLocal. map { " /usr/local/ \( $0) /lib " } + [ " /usr/lib64 " ] ,
195+ defaultSettings: [ : ] ,
196+ overrideSettings: [ : ] ,
197+ defaultSettingsWhenPrimary: [ : ] ,
198+ executableSearchPaths: realSwiftPath. dirname. relativeSubpath ( from: path) . map { [ path. join ( $0) . join ( " bin " ) ] } ?? [ ] ,
199+ testingLibraryPlatformNames: [ ] ,
200+ fs: fs)
201+ ]
173202 }
174203}
175204
0 commit comments