@@ -99,6 +99,12 @@ public final class Toolchain: Sendable {
99
99
/// The path to the Swift language server if available.
100
100
package let sourcekitd : URL ?
101
101
102
+ /// The path to the SourceKit client plugin if available.
103
+ package let sourceKitClientPlugin : URL ?
104
+
105
+ /// The path to the SourceKit plugin if available.
106
+ package let sourceKitServicePlugin : URL ?
107
+
102
108
/// The path to the indexstore library if available.
103
109
package let libIndexStore : URL ?
104
110
@@ -153,6 +159,8 @@ public final class Toolchain: Sendable {
153
159
swiftFormat: URL ? = nil ,
154
160
clangd: URL ? = nil ,
155
161
sourcekitd: URL ? = nil ,
162
+ sourceKitClientPlugin: URL ? = nil ,
163
+ sourceKitServicePlugin: URL ? = nil ,
156
164
libIndexStore: URL ? = nil
157
165
) {
158
166
self . identifier = identifier
@@ -164,6 +172,8 @@ public final class Toolchain: Sendable {
164
172
self . swiftFormat = swiftFormat
165
173
self . clangd = clangd
166
174
self . sourcekitd = sourcekitd
175
+ self . sourceKitClientPlugin = sourceKitClientPlugin
176
+ self . sourceKitServicePlugin = sourceKitServicePlugin
167
177
self . libIndexStore = libIndexStore
168
178
}
169
179
@@ -225,6 +235,8 @@ extension Toolchain {
225
235
var swiftc : URL ? = nil
226
236
var swiftFormat : URL ? = nil
227
237
var sourcekitd : URL ? = nil
238
+ var sourceKitClientPlugin : URL ? = nil
239
+ var sourceKitServicePlugin : URL ? = nil
228
240
var libIndexStore : URL ? = nil
229
241
230
242
if let ( infoPlist, xctoolchainPath) = containingXCToolchain ( path) {
@@ -282,34 +294,53 @@ extension Toolchain {
282
294
}
283
295
284
296
// If 'currentPlatform' is nil it's most likely an unknown linux flavor.
285
- let dylibExt : String
297
+ let dylibExtension : String
286
298
if let dynamicLibraryExtension = Platform . current? . dynamicLibraryExtension {
287
- dylibExt = dynamicLibraryExtension
299
+ dylibExtension = dynamicLibraryExtension
288
300
} else {
289
301
logger. fault ( " Could not determine host OS. Falling back to using '.so' as dynamic library extension " )
290
- dylibExt = " .so "
302
+ dylibExtension = " .so "
291
303
}
292
304
293
- let sourcekitdPath = libPath. appendingPathComponent ( " sourcekitd.framework " ) . appendingPathComponent ( " sourcekitd " )
294
- if FileManager . default. isFile ( at: sourcekitdPath) {
295
- sourcekitd = sourcekitdPath
296
- foundAny = true
297
- } else {
305
+ func findDylib( named name: String , searchFramework: Bool = false ) -> URL ? {
306
+ let frameworkPath = libPath. appendingPathComponent ( " \( name) .framework " ) . appendingPathComponent ( name)
307
+ if FileManager . default. isFile ( at: frameworkPath) {
308
+ return frameworkPath
309
+ }
310
+ let libSearchPath = libPath. appendingPathComponent ( " lib \( name) \( dylibExtension) " )
311
+ if FileManager . default. isFile ( at: libSearchPath) {
312
+ return libSearchPath
313
+ }
298
314
#if os(Windows)
299
- let sourcekitdPath = binPath. appendingPathComponent ( " sourcekitdInProc \( dylibExt) " )
300
- #else
301
- let sourcekitdPath = libPath. appendingPathComponent ( " libsourcekitdInProc \( dylibExt) " )
302
- #endif
303
- if FileManager . default. isFile ( at: sourcekitdPath) {
304
- sourcekitd = sourcekitdPath
305
- foundAny = true
315
+ let binSearchPath = binPath. appendingPathComponent ( " \( name) \( dylibExtension) " )
316
+ if FileManager . default. isFile ( at: binSearchPath) {
317
+ return binSearchPath
306
318
}
319
+ #endif
320
+ return nil
321
+ }
322
+
323
+ if let sourcekitdPath = findDylib ( named: " sourcekitd " , searchFramework: true )
324
+ ?? findDylib ( named: " sourcekitdInProc " )
325
+ {
326
+ sourcekitd = sourcekitdPath
327
+ foundAny = true
328
+ }
329
+
330
+ if let clientPluginPath = findDylib ( named: " SwiftSourceKitClientPlugin " , searchFramework: true ) {
331
+ sourceKitClientPlugin = clientPluginPath
332
+ foundAny = true
333
+ }
334
+
335
+ if let servicePluginPath = findDylib ( named: " SwiftSourceKitPlugin " , searchFramework: true ) {
336
+ sourceKitServicePlugin = servicePluginPath
337
+ foundAny = true
307
338
}
308
339
309
340
#if os(Windows)
310
- let libIndexStorePath = binPath. appendingPathComponent ( " libIndexStore \( dylibExt ) " )
341
+ let libIndexStorePath = binPath. appendingPathComponent ( " libIndexStore \( dylibExtension ) " )
311
342
#else
312
- let libIndexStorePath = libPath. appendingPathComponent ( " libIndexStore \( dylibExt ) " )
343
+ let libIndexStorePath = libPath. appendingPathComponent ( " libIndexStore \( dylibExtension ) " )
313
344
#endif
314
345
if FileManager . default. isFile ( at: libIndexStorePath) {
315
346
libIndexStore = libIndexStorePath
@@ -334,6 +365,8 @@ extension Toolchain {
334
365
swiftFormat: swiftFormat,
335
366
clangd: clangd,
336
367
sourcekitd: sourcekitd,
368
+ sourceKitClientPlugin: sourceKitClientPlugin,
369
+ sourceKitServicePlugin: sourceKitServicePlugin,
337
370
libIndexStore: libIndexStore
338
371
)
339
372
}
0 commit comments