@@ -99,6 +99,12 @@ public final class Toolchain: Sendable {
9999 /// The path to the Swift language server if available.
100100 package let sourcekitd : URL ?
101101
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+
102108 /// The path to the indexstore library if available.
103109 package let libIndexStore : URL ?
104110
@@ -153,6 +159,8 @@ public final class Toolchain: Sendable {
153159 swiftFormat: URL ? = nil ,
154160 clangd: URL ? = nil ,
155161 sourcekitd: URL ? = nil ,
162+ sourceKitClientPlugin: URL ? = nil ,
163+ sourceKitServicePlugin: URL ? = nil ,
156164 libIndexStore: URL ? = nil
157165 ) {
158166 self . identifier = identifier
@@ -164,6 +172,8 @@ public final class Toolchain: Sendable {
164172 self . swiftFormat = swiftFormat
165173 self . clangd = clangd
166174 self . sourcekitd = sourcekitd
175+ self . sourceKitClientPlugin = sourceKitClientPlugin
176+ self . sourceKitServicePlugin = sourceKitServicePlugin
167177 self . libIndexStore = libIndexStore
168178 }
169179
@@ -223,6 +233,8 @@ public final class Toolchain: Sendable {
223233 var swiftc : URL ? = nil
224234 var swiftFormat : URL ? = nil
225235 var sourcekitd : URL ? = nil
236+ var sourceKitClientPlugin : URL ? = nil
237+ var sourceKitServicePlugin : URL ? = nil
226238 var libIndexStore : URL ? = nil
227239
228240 if let ( infoPlist, xctoolchainPath) = containingXCToolchain ( path) {
@@ -280,34 +292,53 @@ public final class Toolchain: Sendable {
280292 }
281293
282294 // If 'currentPlatform' is nil it's most likely an unknown linux flavor.
283- let dylibExt : String
295+ let dylibExtension : String
284296 if let dynamicLibraryExtension = Platform . current? . dynamicLibraryExtension {
285- dylibExt = dynamicLibraryExtension
297+ dylibExtension = dynamicLibraryExtension
286298 } else {
287299 logger. fault ( " Could not determine host OS. Falling back to using '.so' as dynamic library extension " )
288- dylibExt = " .so "
300+ dylibExtension = " .so "
289301 }
290302
291- let sourcekitdPath = libPath. appendingPathComponent ( " sourcekitd.framework " ) . appendingPathComponent ( " sourcekitd " )
292- if FileManager . default. isFile ( at: sourcekitdPath) {
293- sourcekitd = sourcekitdPath
294- foundAny = true
295- } else {
303+ func findDylib( named name: String , searchFramework: Bool = false ) -> URL ? {
304+ let frameworkPath = libPath. appendingPathComponent ( " \( name) .framework " ) . appendingPathComponent ( name)
305+ if FileManager . default. isFile ( at: frameworkPath) {
306+ return frameworkPath
307+ }
308+ let libSearchPath = libPath. appendingPathComponent ( " lib \( name) \( dylibExtension) " )
309+ if FileManager . default. isFile ( at: libSearchPath) {
310+ return libSearchPath
311+ }
296312 #if os(Windows)
297- let sourcekitdPath = binPath. appendingPathComponent ( " sourcekitdInProc \( dylibExt) " )
298- #else
299- let sourcekitdPath = libPath. appendingPathComponent ( " libsourcekitdInProc \( dylibExt) " )
300- #endif
301- if FileManager . default. isFile ( at: sourcekitdPath) {
302- sourcekitd = sourcekitdPath
303- foundAny = true
313+ let binSearchPath = binPath. appendingPathComponent ( " \( name) \( dylibExtension) " )
314+ if FileManager . default. isFile ( at: binSearchPath) {
315+ return binSearchPath
304316 }
317+ #endif
318+ return nil
319+ }
320+
321+ if let sourcekitdPath = findDylib ( named: " sourcekitd " , searchFramework: true )
322+ ?? findDylib ( named: " sourcekitdInProc " )
323+ {
324+ sourcekitd = sourcekitdPath
325+ foundAny = true
326+ }
327+
328+ if let clientPluginPath = findDylib ( named: " SwiftSourceKitClientPlugin " , searchFramework: true ) {
329+ sourceKitClientPlugin = clientPluginPath
330+ foundAny = true
331+ }
332+
333+ if let servicePluginPath = findDylib ( named: " SwiftSourceKitPlugin " , searchFramework: true ) {
334+ sourceKitServicePlugin = servicePluginPath
335+ foundAny = true
305336 }
306337
307338 #if os(Windows)
308- let libIndexStorePath = binPath. appendingPathComponent ( " libIndexStore \( dylibExt ) " )
339+ let libIndexStorePath = binPath. appendingPathComponent ( " libIndexStore \( dylibExtension ) " )
309340 #else
310- let libIndexStorePath = libPath. appendingPathComponent ( " libIndexStore \( dylibExt ) " )
341+ let libIndexStorePath = libPath. appendingPathComponent ( " libIndexStore \( dylibExtension ) " )
311342 #endif
312343 if FileManager . default. isFile ( at: libIndexStorePath) {
313344 libIndexStore = libIndexStorePath
@@ -332,6 +363,8 @@ public final class Toolchain: Sendable {
332363 swiftFormat: swiftFormat,
333364 clangd: clangd,
334365 sourcekitd: sourcekitd,
366+ sourceKitClientPlugin: sourceKitClientPlugin,
367+ sourceKitServicePlugin: sourceKitServicePlugin,
335368 libIndexStore: libIndexStore
336369 )
337370 }
0 commit comments