Skip to content

[SourceKit] Do not hardcode the XPC service name #79530

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Mar 4, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion tools/SourceKit/cmake/modules/AddSwiftSourceKit.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -445,6 +445,9 @@ macro(add_sourcekit_framework name)
"${framework_location}/Versions/A" "${SOURCEKIT_LIBRARY_OUTPUT_INTDIR}")
list(APPEND RPATH_LIST "@loader_path/${relative_lib_path}")

file(GENERATE OUTPUT "xpc_service_name.txt" CONTENT "com.apple.SourceKitService.${SOURCEKIT_VERSION_STRING}_${SOURCEKIT_TOOLCHAIN_NAME}")
target_sources(${name} PRIVATE "${CMAKE_CURRENT_BINARY_DIR}/xpc_service_name.txt")

set_target_properties(${name} PROPERTIES
BUILD_WITH_INSTALL_RPATH TRUE
FOLDER "SourceKit frameworks"
Expand All @@ -455,7 +458,8 @@ macro(add_sourcekit_framework name)
MACOSX_FRAMEWORK_IDENTIFIER "com.apple.${name}"
MACOSX_FRAMEWORK_SHORT_VERSION_STRING "1.0"
MACOSX_FRAMEWORK_BUNDLE_VERSION "${SOURCEKIT_VERSION_STRING}"
PUBLIC_HEADER "${headers}")
PUBLIC_HEADER "${headers}"
RESOURCE "${CMAKE_CURRENT_BINARY_DIR}/xpc_service_name.txt")
add_dependencies(${SOURCEKITFW_INSTALL_IN_COMPONENT} ${name})
swift_install_in_component(TARGETS ${name}
FRAMEWORK
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,6 @@ add_sourcekit_framework(sourcekitd
)
target_link_libraries(sourcekitd PRIVATE sourcekitdAPI)

add_definitions(-DSOURCEKIT_XPCSERVICE_IDENTIFIER="com.apple.SourceKitService.${SOURCEKIT_VERSION_STRING}_${SOURCEKIT_TOOLCHAIN_NAME}")

if (SOURCEKIT_BUILT_STANDALONE)
# Create the symlink necessary to find the swift stdlib.
swift_create_post_build_symlink(sourcekitd
Expand Down
35 changes: 31 additions & 4 deletions tools/SourceKit/tools/sourcekitd/bin/XPC/Client/sourcekitd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
#include "SourceKit/Support/UIdent.h"

#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/MemoryBuffer.h"
#include "llvm/Support/Mutex.h"
#include "llvm/Support/Path.h"

#include <Block.h>
#include <chrono>
#include <xpc/xpc.h>
#include <dispatch/dispatch.h>

#include <Block.h>
#include <dlfcn.h>

using namespace SourceKit;
using namespace sourcekitd;
Expand Down Expand Up @@ -285,9 +288,31 @@ static void handleInternalUIDRequest(xpc_object_t XVal,

static void handleInterruptedConnection(xpc_object_t event, xpc_connection_t conn);

extern "C" const char __dso_handle[];

static void initializeXPCClient() {
assert(!GlobalConn);
GlobalConn = xpc_connection_create(SOURCEKIT_XPCSERVICE_IDENTIFIER, nullptr);

Dl_info dlinfo;
dladdr(__dso_handle, &dlinfo);

// '.../usr/lib/sourcekitd.framework/sourcekitd'
llvm::SmallString<128> serviceNamePath(dlinfo.dli_fname);
if (serviceNamePath.empty()) {
llvm::report_fatal_error("Unable to find service name path");
}

llvm::sys::path::remove_filename(serviceNamePath);
// '.../usr/lib/sourcekitd.framework/Resources/xpc_service_name.txt'
llvm::sys::path::append(serviceNamePath, "Resources", "xpc_service_name.txt");

auto bufferOrErr = llvm::MemoryBuffer::getFile(serviceNamePath);
if (!bufferOrErr) {
llvm::report_fatal_error("Unable to find service name");
}

std::string serviceName = (*bufferOrErr)->getBuffer().trim().str();
GlobalConn = xpc_connection_create(serviceName.c_str(), nullptr);

xpc_connection_set_event_handler(GlobalConn, ^(xpc_object_t event) {
xpc_type_t type = xpc_get_type(event);
Expand Down Expand Up @@ -390,7 +415,9 @@ void sourcekitd_register_plugin_path(const char *clientPlugin,
}

static xpc_connection_t getGlobalConnection() {
assert(GlobalConn);
if (!GlobalConn) {
llvm::report_fatal_error("Service is invalid");
}
return GlobalConn;
}

Expand Down