@@ -49,12 +49,6 @@ struct SwiftTargetInfo: Decodable {
4949 let target : TargetInfo
5050}
5151
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- }
56- }
57-
5852struct GenericUnixDeveloperDirectoryExtension : DeveloperDirectoryExtension {
5953 func fallbackDeveloperDirectory( hostOperatingSystem: OperatingSystem ) async throws -> Core . DeveloperPath ? {
6054 if hostOperatingSystem == . windows || hostOperatingSystem == . macOS {
@@ -82,13 +76,12 @@ struct GenericUnixPlatformSpecsExtension: SpecificationsExtension {
8276
8377struct GenericUnixPlatformInfoExtension : PlatformInfoExtension {
8478 func additionalPlatforms( context: any PlatformInfoExtensionAdditionalPlatformsContext ) throws -> [ ( path: Path , data: [ String : PropertyListItem ] ) ] {
85- let operatingSystem = context. hostOperatingSystem
86- guard operatingSystem. createFallbackSystemToolchain else {
87- return [ ]
88- }
89-
90- return try [
91- ( . root, [
79+ return try OperatingSystem . createFallbackSystemToolchains. compactMap { operatingSystem in
80+ // Only create platforms if the host OS allows a fallback toolchain, or we're cross compiling.
81+ guard operatingSystem. createFallbackSystemToolchain || operatingSystem != context. hostOperatingSystem else {
82+ return nil
83+ }
84+ return try ( . root, [
9285 " Type " : . plString( " Platform " ) ,
9386 " Name " : . plString( operatingSystem. xcodePlatformName) ,
9487 " Identifier " : . plString( operatingSystem. xcodePlatformName) ,
@@ -97,78 +90,156 @@ struct GenericUnixPlatformInfoExtension: PlatformInfoExtension {
9790 " FamilyIdentifier " : . plString( operatingSystem. xcodePlatformName) ,
9891 " IsDeploymentPlatform " : . plString( " YES " ) ,
9992 ] )
100- ]
93+ }
10194 }
10295}
10396
10497struct GenericUnixSDKRegistryExtension : SDKRegistryExtension {
10598 let plugin : GenericUnixPlugin
10699
107100 func additionalSDKs( context: any SDKRegistryExtensionAdditionalSDKsContext ) async throws -> [ ( path: Path , platform: SWBCore . Platform ? , data: [ String : PropertyListItem ] ) ] {
108- let operatingSystem = context. hostOperatingSystem
109- guard operatingSystem. createFallbackSystemToolchain, let platform = try context. platformRegistry. lookup ( name: operatingSystem. xcodePlatformName) , let swift = plugin. swiftExecutablePath ( fs: context. fs) else {
110- return [ ]
111- }
101+ return try await OperatingSystem . createFallbackSystemToolchains. asyncMap { operatingSystem in
102+ // Only create SDKs if the host OS allows a fallback toolchain, or we're cross compiling.
103+ guard operatingSystem. createFallbackSystemToolchain || operatingSystem != context. hostOperatingSystem else {
104+ return nil
105+ }
112106
113- let defaultProperties : [ String : PropertyListItem ]
114- switch operatingSystem {
115- case . linux, . freebsd:
116- defaultProperties = [
117- // Workaround to avoid `-dependency_info`.
118- " LD_DEPENDENCY_INFO_FILE " : . plString( " " ) ,
119-
120- " GENERATE_TEXT_BASED_STUBS " : " NO " ,
121- " GENERATE_INTERMEDIATE_TEXT_BASED_STUBS " : " NO " ,
122-
123- " CHOWN " : " /usr/bin/chown " ,
124- " AR " : " llvm-ar " ,
125- ]
126- default :
127- defaultProperties = [ : ]
128- }
107+ // Don't create any SDKs for the platform if the platform itself isn't registered.
108+ guard let platform = try context. platformRegistry. lookup ( name: operatingSystem. xcodePlatformName) else {
109+ return nil
110+ }
129111
130- let tripleEnvironment : String
131- switch operatingSystem {
132- case . linux:
133- tripleEnvironment = " gnu "
134- default :
135- tripleEnvironment = " "
136- }
112+ var defaultProperties : [ String : PropertyListItem ]
113+ switch operatingSystem {
114+ case . linux, . freebsd:
115+ defaultProperties = [
116+ // Workaround to avoid `-dependency_info`.
117+ " LD_DEPENDENCY_INFO_FILE " : . plString( " " ) ,
137118
138- let swiftTargetInfo = try await plugin. swiftTargetInfo ( swiftExecutablePath: swift)
119+ " GENERATE_TEXT_BASED_STUBS " : " NO " ,
120+ " GENERATE_INTERMEDIATE_TEXT_BASED_STUBS " : " NO " ,
139121
140- let deploymentTargetSettings : [ String : PropertyListItem ]
141- if operatingSystem == . freebsd {
142- guard let tripleVersion = swiftTargetInfo. target. tripleVersion else {
143- throw StubError . error ( " Unknown FreeBSD triple version " )
122+ " CHOWN " : " /usr/bin/chown " ,
123+ " AR " : " llvm-ar " ,
124+ ]
125+ default :
126+ defaultProperties = [ : ]
144127 }
145- deploymentTargetSettings = [
146- " DeploymentTargetSettingName " : . plString( " FREEBSD_DEPLOYMENT_TARGET " ) ,
147- " DefaultDeploymentTarget " : . plString( tripleVersion) ,
148- " MinimumDeploymentTarget " : . plString( tripleVersion) ,
149- " MaximumDeploymentTarget " : . plString( tripleVersion) ,
150- ]
151- } else {
152- deploymentTargetSettings = [ : ]
153- }
154128
155- return try [ ( . root, platform, [
156- " Type " : . plString( " SDK " ) ,
157- " Version " : . plString( Version ( ProcessInfo . processInfo. operatingSystemVersion) . zeroTrimmed. description) ,
158- " CanonicalName " : . plString( operatingSystem. xcodePlatformName) ,
159- " IsBaseSDK " : . plBool( true ) ,
160- " DefaultProperties " : . plDict( [
161- " PLATFORM_NAME " : . plString( operatingSystem. xcodePlatformName) ,
162- ] . merging ( defaultProperties, uniquingKeysWith: { _, new in new } ) ) ,
163- " SupportedTargets " : . plDict( [
164- operatingSystem. xcodePlatformName: . plDict( [
165- " Archs " : . plArray( [ . plString( Architecture . hostStringValue ?? " unknown " ) ] ) ,
166- " LLVMTargetTripleEnvironment " : . plString( tripleEnvironment) ,
167- " LLVMTargetTripleSys " : . plString( operatingSystem. xcodePlatformName) ,
168- " LLVMTargetTripleVendor " : . plString( " unknown " ) ,
169- ] . merging ( deploymentTargetSettings, uniquingKeysWith: { _, new in new } ) )
170- ] ) ,
171- ] ) ]
129+ if operatingSystem == . freebsd || operatingSystem != context. hostOperatingSystem {
130+ // FreeBSD is always LLVM-based, and if we're cross-compiling, use lld
131+ defaultProperties [ " ALTERNATE_LINKER " ] = " lld "
132+ }
133+
134+ let tripleEnvironment : String
135+ switch operatingSystem {
136+ case . linux:
137+ tripleEnvironment = " gnu "
138+ default :
139+ tripleEnvironment = " "
140+ }
141+
142+ let swiftSDK : SwiftSDK ?
143+ let sysroot : Path
144+ let architectures : [ String ]
145+ let tripleVersion : String ?
146+ let customProperties : [ String : PropertyListItem ]
147+ if operatingSystem == context. hostOperatingSystem {
148+ swiftSDK = nil
149+ sysroot = . root
150+ architectures = [ Architecture . hostStringValue ?? " unknown " ]
151+ tripleVersion = nil
152+ customProperties = [ : ]
153+ } else {
154+ do {
155+ let swiftSDKs = try SwiftSDK . findSDKs (
156+ targetTriples: nil ,
157+ fs: context. fs,
158+ hostOperatingSystem: context. hostOperatingSystem
159+ ) . filter { sdk in
160+ try sdk. targetTriples. keys. map {
161+ try LLVMTriple ( $0)
162+ } . contains {
163+ switch operatingSystem {
164+ case . linux:
165+ $0. system == " linux " && $0. environment? . hasPrefix ( " gnu " ) == true
166+ case . freebsd:
167+ $0. system == " freebsd "
168+ case . openbsd:
169+ $0. system == " openbsd "
170+ default :
171+ throw StubError . error ( " Unhandled operating system: \( operatingSystem) " )
172+ }
173+ }
174+ }
175+ // FIXME: Do something better than just skipping the platform if more than one SDK matches
176+ swiftSDK = swiftSDKs. only
177+ guard let swiftSDK else {
178+ return nil
179+ }
180+ sysroot = swiftSDK. path
181+ architectures = try swiftSDK. targetTriples. keys. map { try LLVMTriple ( $0) . arch } . sorted ( )
182+ tripleVersion = try Set ( swiftSDK. targetTriples. keys. compactMap { try LLVMTriple ( $0) . systemVersion } ) . only? . description
183+ customProperties = try Dictionary ( uniqueKeysWithValues: swiftSDK. targetTriples. map { targetTriple in
184+ try ( " __SYSROOT_ \( LLVMTriple ( targetTriple. key) . arch) " , . plString( swiftSDK. path. join ( targetTriple. value. sdkRootPath) . str) )
185+ } ) . merging ( [
186+ " SYSROOT " : " $(__SYSROOT_$(CURRENT_ARCH)) " ,
187+
188+ // ld.lld: error: -r and --export-dynamic (-rdynamic) may not be used together
189+ " LD_EXPORT_GLOBAL_SYMBOLS " : " YES " ,
190+ ] , uniquingKeysWith: { _, new in new } )
191+ } catch {
192+ // FIXME: Handle errors?
193+ return nil
194+ }
195+ }
196+
197+ let deploymentTargetSettings : [ String : PropertyListItem ]
198+ if operatingSystem == . freebsd {
199+ let realTripleVersion : String
200+ if context. hostOperatingSystem == operatingSystem {
201+ guard let swift = plugin. swiftExecutablePath ( fs: context. fs) else {
202+ throw StubError . error ( " Cannot locate swift executable path for determining the FreeBSD triple version " )
203+ }
204+ let swiftTargetInfo = try await plugin. swiftTargetInfo ( swiftExecutablePath: swift)
205+ guard let foundTripleVersion = try swiftTargetInfo. target. triple. version? . description else {
206+ throw StubError . error ( " Unknown FreeBSD triple version " )
207+ }
208+ realTripleVersion = foundTripleVersion
209+ } else if let tripleVersion {
210+ realTripleVersion = tripleVersion
211+ } else {
212+ return nil // couldn't compute triple version for FreeBSD
213+ }
214+ deploymentTargetSettings = [
215+ " DeploymentTargetSettingName " : . plString( " FREEBSD_DEPLOYMENT_TARGET " ) ,
216+ " DefaultDeploymentTarget " : . plString( realTripleVersion) ,
217+ " MinimumDeploymentTarget " : . plString( realTripleVersion) ,
218+ " MaximumDeploymentTarget " : . plString( realTripleVersion) ,
219+ ]
220+ } else {
221+ deploymentTargetSettings = [ : ]
222+ }
223+
224+ return try ( sysroot, platform, [
225+ " Type " : . plString( " SDK " ) ,
226+ " Version " : . plString( Version ( ProcessInfo . processInfo. operatingSystemVersion) . zeroTrimmed. description) ,
227+ " CanonicalName " : . plString( operatingSystem. xcodePlatformName) ,
228+ " IsBaseSDK " : . plBool( true ) ,
229+ " DefaultProperties " : . plDict( [
230+ " PLATFORM_NAME " : . plString( operatingSystem. xcodePlatformName) ,
231+ ] . merging ( defaultProperties, uniquingKeysWith: { _, new in new } ) ) ,
232+ " CustomProperties " : . plDict( customProperties) ,
233+ " SupportedTargets " : . plDict( [
234+ operatingSystem. xcodePlatformName: . plDict( [
235+ " Archs " : . plArray( architectures. map { . plString( $0) } ) ,
236+ " LLVMTargetTripleEnvironment " : . plString( tripleEnvironment) ,
237+ " LLVMTargetTripleSys " : . plString( operatingSystem. xcodePlatformName) ,
238+ " LLVMTargetTripleVendor " : . plString( " unknown " ) ,
239+ ] . merging ( deploymentTargetSettings, uniquingKeysWith: { _, new in new } ) )
240+ ] ) ,
241+ ] )
242+ } . compactMap { $0 }
172243 }
173244}
174245
@@ -218,8 +289,12 @@ struct GenericUnixToolchainRegistryExtension: ToolchainRegistryExtension {
218289}
219290
220291extension OperatingSystem {
292+ static var createFallbackSystemToolchains : [ OperatingSystem ] {
293+ [ . linux, . freebsd, . openbsd]
294+ }
295+
221296 /// Whether the Core is allowed to create a fallback toolchain, SDK, and platform for this operating system in cases where no others have been provided.
222- var createFallbackSystemToolchain : Bool {
223- return self == . linux || self == . freebsd || self == . openbsd
297+ fileprivate var createFallbackSystemToolchain : Bool {
298+ return Self . createFallbackSystemToolchains . contains ( self )
224299 }
225300}
0 commit comments