@@ -212,6 +212,63 @@ static bool findXcodeClangLibPath(const Twine &libName,
212
212
return true ;
213
213
}
214
214
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
+
215
272
static void addVersionString (const ArgList &inputArgs, ArgStringList &arguments,
216
273
llvm::VersionTuple version) {
217
274
llvm::SmallString<8 > buf;
@@ -601,6 +658,46 @@ void toolchains::Darwin::addCommonFrontendArgs(
601
658
llvm::opt::ArgStringList &arguments) const {
602
659
ToolChain::addCommonFrontendArgs (OI, output, inputArgs, arguments);
603
660
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
+
604
701
if (auto sdkVersion = getTargetSDKVersion (getTriple ())) {
605
702
arguments.push_back (" -target-sdk-version" );
606
703
arguments.push_back (inputArgs.MakeArgString (sdkVersion->getAsString ()));
0 commit comments