@@ -143,6 +143,10 @@ final class RequestHandler: Sendable {
143143 }
144144}
145145
146+ #if compiler(>=6.3)
147+ #warning("Remove sourcekitd_plugin_initialize when we no longer support toolchains that call it")
148+ #endif
149+
146150/// Legacy plugin initialization logic in which sourcekitd does not inform the plugin about the sourcekitd path it was
147151/// loaded from.
148152@_cdecl ( " sourcekitd_plugin_initialize " )
@@ -160,8 +164,16 @@ public func sourcekitd_plugin_initialize(_ params: sourcekitd_api_plugin_initial
160164 . deletingLastPathComponent ( )
161165 . appendingPathComponent ( " sourcekitd.framework " )
162166 . 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 " )
165177 }
166178 #else
167179 fatalError ( " sourcekitd_plugin_initialize is not supported on non-Darwin platforms " )
@@ -223,15 +235,24 @@ public func sourcekitd_plugin_initialize_2(
223235 _ params: sourcekitd_api_plugin_initialize_params_t ,
224236 _ parentLibraryPath: UnsafePointer < CChar >
225237) {
238+ let parentLibraryPath = String ( cString: parentLibraryPath)
226239 #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+ }
231252 #else
232253 // On other platforms, sourcekitd is always in process, so we can load it straight away.
233254 DynamicallyLoadedSourceKitD . forPlugin = try ! DynamicallyLoadedSourceKitD (
234- dylib: URL ( fileURLWithPath: String ( cString : parentLibraryPath) ) ,
255+ dylib: URL ( fileURLWithPath: parentLibraryPath) ,
235256 pluginPaths: nil ,
236257 initialize: false
237258 )
0 commit comments