Skip to content

Commit 5d20a3a

Browse files
committed
[Driver] Derive '-external-plugin-path'
When the current toolchain is not a Xcode toolchain, derive '-external-plugin-path' poinintng Xcode plugins paths, so we can use plugins in Xcode. rdar://108624128 (cherry picked from commit 3d8b9c9)
1 parent f023fd3 commit 5d20a3a

File tree

2 files changed

+97
-2
lines changed

2 files changed

+97
-2
lines changed

lib/Driver/DarwinToolChains.cpp

Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,63 @@ static bool findXcodeClangLibPath(const Twine &libName,
212212
return true;
213213
}
214214

215+
static bool findXcodeExecutableDir(llvm::SmallVectorImpl<char> &path) {
216+
assert(path.empty());
217+
218+
auto xcrunPath = llvm::sys::findProgramByName("xcrun");
219+
if (!xcrunPath.getError()) {
220+
// Explicitly ask for the default toolchain so that we don't find a Clang
221+
// included with an open-source toolchain.
222+
const char *args[] = {"-toolchain", "default", "-f", "swiftc", nullptr};
223+
sys::TaskQueue queue;
224+
queue.addTask(xcrunPath->c_str(), args, /*Env=*/llvm::None,
225+
/*Context=*/nullptr,
226+
/*SeparateErrors=*/true);
227+
queue.execute(nullptr,
228+
[&path](sys::ProcessId PID, int returnCode, StringRef output,
229+
StringRef errors,
230+
sys::TaskProcessInformation ProcInfo,
231+
void *unused) -> sys::TaskFinishedResponse {
232+
if (returnCode == 0) {
233+
output = output.rtrim();
234+
path.append(output.begin(), output.end());
235+
llvm::sys::path::remove_filename(path); // 'swiftc'
236+
}
237+
return sys::TaskFinishedResponse::ContinueExecution;
238+
});
239+
}
240+
241+
return !path.empty();
242+
}
243+
244+
static bool findCurrentSelectedXcodeDir(llvm::SmallVectorImpl<char> &path) {
245+
assert(path.empty());
246+
247+
auto xcrunPath = llvm::sys::findProgramByName("xcode-select");
248+
if (!xcrunPath.getError()) {
249+
// Explicitly ask for the default toolchain so that we don't find a Clang
250+
// included with an open-source toolchain.
251+
const char *args[] = {"-p", nullptr};
252+
sys::TaskQueue queue;
253+
queue.addTask(xcrunPath->c_str(), args, /*Env=*/llvm::None,
254+
/*Context=*/nullptr,
255+
/*SeparateErrors=*/true);
256+
queue.execute(nullptr,
257+
[&path](sys::ProcessId PID, int returnCode, StringRef output,
258+
StringRef errors,
259+
sys::TaskProcessInformation ProcInfo,
260+
void *unused) -> sys::TaskFinishedResponse {
261+
if (returnCode == 0) {
262+
output = output.rtrim();
263+
path.append(output.begin(), output.end());
264+
}
265+
return sys::TaskFinishedResponse::ContinueExecution;
266+
});
267+
}
268+
269+
return !path.empty();
270+
}
271+
215272
static void addVersionString(const ArgList &inputArgs, ArgStringList &arguments,
216273
llvm::VersionTuple version) {
217274
llvm::SmallString<8> buf;
@@ -601,6 +658,46 @@ void toolchains::Darwin::addCommonFrontendArgs(
601658
llvm::opt::ArgStringList &arguments) const {
602659
ToolChain::addCommonFrontendArgs(OI, output, inputArgs, arguments);
603660

661+
// Pass -external-plugin-path if the current toolchain is not a Xcode default
662+
// toolchain.
663+
{
664+
// 'xcode-select -p'
665+
SmallString<256> xcodeDir;
666+
if (findCurrentSelectedXcodeDir(xcodeDir) &&
667+
!StringRef(getDriver().getSwiftProgramPath()).starts_with(xcodeDir)) {
668+
669+
// 'xcrun -f swiftc'
670+
SmallString<256> xcodeExecutableDir;
671+
if (findXcodeExecutableDir(xcodeExecutableDir)) {
672+
using namespace llvm::sys;
673+
674+
// '${toolchain}/usr/bin/swift-plugin-server'
675+
SmallString<256> xcodePluginServerPath(xcodeExecutableDir);
676+
path::append(xcodePluginServerPath, "swift-plugin-server");
677+
if (fs::can_execute(xcodePluginServerPath)) {
678+
679+
// '${toolchain}/usr/lib/swift/host/plugins'
680+
SmallString<256> xcodePluginPath(xcodeExecutableDir);
681+
path::remove_filename(xcodePluginPath); // 'bin'
682+
path::append(xcodePluginPath, "lib", "swift", "host", "plugins");
683+
684+
// '${toolchain}/usr/locallib/swift/host/plugins'
685+
SmallString<256> xcodeLocalPluginPath(xcodeExecutableDir);
686+
path::remove_filename(xcodeLocalPluginPath); // 'bin'
687+
path::append(xcodeLocalPluginPath, "local");
688+
path::append(xcodeLocalPluginPath, "lib", "swift", "host", "plugins");
689+
690+
arguments.push_back("-external-plugin-path");
691+
arguments.push_back(inputArgs.MakeArgString(xcodePluginPath + "#" +
692+
xcodePluginServerPath));
693+
arguments.push_back("-external-plugin-path");
694+
arguments.push_back(inputArgs.MakeArgString(
695+
xcodeLocalPluginPath + "#" + xcodePluginServerPath));
696+
}
697+
}
698+
}
699+
}
700+
604701
if (auto sdkVersion = getTargetSDKVersion(getTriple())) {
605702
arguments.push_back("-target-sdk-version");
606703
arguments.push_back(inputArgs.MakeArgString(sdkVersion->getAsString()));

lib/Driver/ToolChains.cpp

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -377,8 +377,6 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
377377
}
378378

379379
// Add plugin path options.
380-
inputArgs.AddAllArgs(arguments, options::OPT_plugin_path);
381-
382380
{
383381
SmallString<64> pluginPath;
384382
auto programPath = getDriver().getSwiftProgramPath();

0 commit comments

Comments
 (0)