@@ -143,6 +143,10 @@ final class RequestHandler: Sendable {
143
143
}
144
144
}
145
145
146
+ #if compiler(>=6.3)
147
+ #warning("Remove sourcekitd_plugin_initialize when we no longer support toolchains that call it")
148
+ #endif
149
+
146
150
/// Legacy plugin initialization logic in which sourcekitd does not inform the plugin about the sourcekitd path it was
147
151
/// loaded from.
148
152
@_cdecl ( " sourcekitd_plugin_initialize " )
@@ -160,8 +164,16 @@ public func sourcekitd_plugin_initialize(_ params: sourcekitd_api_plugin_initial
160
164
. deletingLastPathComponent ( )
161
165
. appendingPathComponent ( " sourcekitd.framework " )
162
166
. appendingPathComponent ( " sourcekitd " )
163
- try ! url. filePath. withCString { sourcekitdPath in
164
- sourcekitd_plugin_initialize_2 ( params, sourcekitdPath)
167
+ if FileManager . default. fileExists ( at: url) {
168
+ try ! url. filePath. withCString { sourcekitdPath in
169
+ sourcekitd_plugin_initialize_2 ( params, sourcekitdPath)
170
+ }
171
+ } else {
172
+ // When using a SourceKit plugin from the build directory, we can't find sourcekitd relative to the plugin.
173
+ // Since sourcekitd_plugin_initialize is only called on Darwin from Xcode toolchains, we know that we are getting
174
+ // called from an XPC sourcekitd. Thus, all sourcekitd symbols that we need should be loaded in the current process
175
+ // already and we can use `RTLD_DEFAULT` for the sourcekitd library.
176
+ sourcekitd_plugin_initialize_2 ( params, " SOURCEKIT_LSP_PLUGIN_PARENT_LIBRARY_RTLD_DEFAULT " )
165
177
}
166
178
#else
167
179
fatalError ( " sourcekitd_plugin_initialize is not supported on non-Darwin platforms " )
@@ -223,15 +235,24 @@ public func sourcekitd_plugin_initialize_2(
223
235
_ params: sourcekitd_api_plugin_initialize_params_t ,
224
236
_ parentLibraryPath: UnsafePointer < CChar >
225
237
) {
238
+ let parentLibraryPath = String ( cString: parentLibraryPath)
226
239
#if canImport(Darwin)
227
- // On macOS, we need to find sourcekitdInProc relative to the library the plugin was loaded from.
228
- DynamicallyLoadedSourceKitD . forPlugin = try ! DynamicallyLoadedSourceKitD . inProcLibrary (
229
- relativeTo: URL ( fileURLWithPath: String ( cString: parentLibraryPath) )
230
- )
240
+ if parentLibraryPath == " SOURCEKIT_LSP_PLUGIN_PARENT_LIBRARY_RTLD_DEFAULT " {
241
+ DynamicallyLoadedSourceKitD . forPlugin = try ! DynamicallyLoadedSourceKitD (
242
+ dlhandle: . rtldDefault,
243
+ path: URL ( string: " rtld-default:// " ) !,
244
+ pluginPaths: nil ,
245
+ initialize: false
246
+ )
247
+ } else {
248
+ DynamicallyLoadedSourceKitD . forPlugin = try ! DynamicallyLoadedSourceKitD . inProcLibrary (
249
+ relativeTo: URL ( fileURLWithPath: String ( cString: parentLibraryPath) )
250
+ )
251
+ }
231
252
#else
232
253
// On other platforms, sourcekitd is always in process, so we can load it straight away.
233
254
DynamicallyLoadedSourceKitD . forPlugin = try ! DynamicallyLoadedSourceKitD (
234
- dylib: URL ( fileURLWithPath: String ( cString : parentLibraryPath) ) ,
255
+ dylib: URL ( fileURLWithPath: parentLibraryPath) ,
235
256
pluginPaths: nil ,
236
257
initialize: false
237
258
)
0 commit comments