@@ -49,12 +49,6 @@ struct SwiftTargetInfo: Decodable {
49
49
let target : TargetInfo
50
50
}
51
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
- }
56
- }
57
-
58
52
struct GenericUnixDeveloperDirectoryExtension : DeveloperDirectoryExtension {
59
53
func fallbackDeveloperDirectory( hostOperatingSystem: OperatingSystem ) async throws -> Core . DeveloperPath ? {
60
54
if hostOperatingSystem == . windows || hostOperatingSystem == . macOS {
@@ -82,13 +76,12 @@ struct GenericUnixPlatformSpecsExtension: SpecificationsExtension {
82
76
83
77
struct GenericUnixPlatformInfoExtension : PlatformInfoExtension {
84
78
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, [
92
85
" Type " : . plString( " Platform " ) ,
93
86
" Name " : . plString( operatingSystem. xcodePlatformName) ,
94
87
" Identifier " : . plString( operatingSystem. xcodePlatformName) ,
@@ -97,78 +90,156 @@ struct GenericUnixPlatformInfoExtension: PlatformInfoExtension {
97
90
" FamilyIdentifier " : . plString( operatingSystem. xcodePlatformName) ,
98
91
" IsDeploymentPlatform " : . plString( " YES " ) ,
99
92
] )
100
- ]
93
+ }
101
94
}
102
95
}
103
96
104
97
struct GenericUnixSDKRegistryExtension : SDKRegistryExtension {
105
98
let plugin : GenericUnixPlugin
106
99
107
100
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
+ }
112
106
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
+ }
129
111
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( " " ) ,
137
118
138
- let swiftTargetInfo = try await plugin. swiftTargetInfo ( swiftExecutablePath: swift)
119
+ " GENERATE_TEXT_BASED_STUBS " : " NO " ,
120
+ " GENERATE_INTERMEDIATE_TEXT_BASED_STUBS " : " NO " ,
139
121
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 = [ : ]
144
127
}
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
- }
154
128
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 }
172
243
}
173
244
}
174
245
@@ -218,8 +289,12 @@ struct GenericUnixToolchainRegistryExtension: ToolchainRegistryExtension {
218
289
}
219
290
220
291
extension OperatingSystem {
292
+ static var createFallbackSystemToolchains : [ OperatingSystem ] {
293
+ [ . linux, . freebsd, . openbsd]
294
+ }
295
+
221
296
/// 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 )
224
299
}
225
300
}
0 commit comments