@@ -212,6 +212,61 @@ 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 swiftc
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 xcodeSelectPath = llvm::sys::findProgramByName (" xcode-select" );
248
+ if (!xcodeSelectPath.getError ()) {
249
+ const char *args[] = {" -p" , nullptr };
250
+ sys::TaskQueue queue;
251
+ queue.addTask (xcodeSelectPath->c_str (), args, /* Env=*/ llvm::None,
252
+ /* Context=*/ nullptr ,
253
+ /* SeparateErrors=*/ true );
254
+ queue.execute (nullptr ,
255
+ [&path](sys::ProcessId PID, int returnCode, StringRef output,
256
+ StringRef errors,
257
+ sys::TaskProcessInformation ProcInfo,
258
+ void *unused) -> sys::TaskFinishedResponse {
259
+ if (returnCode == 0 ) {
260
+ output = output.rtrim ();
261
+ path.append (output.begin (), output.end ());
262
+ }
263
+ return sys::TaskFinishedResponse::ContinueExecution;
264
+ });
265
+ }
266
+
267
+ return !path.empty ();
268
+ }
269
+
215
270
static void addVersionString (const ArgList &inputArgs, ArgStringList &arguments,
216
271
llvm::VersionTuple version) {
217
272
llvm::SmallString<8 > buf;
@@ -601,6 +656,46 @@ void toolchains::Darwin::addCommonFrontendArgs(
601
656
llvm::opt::ArgStringList &arguments) const {
602
657
ToolChain::addCommonFrontendArgs (OI, output, inputArgs, arguments);
603
658
659
+ // Pass -external-plugin-path if the current toolchain is not a Xcode default
660
+ // toolchain.
661
+ {
662
+ // 'xcode-select -p'
663
+ SmallString<256 > xcodeDir;
664
+ if (findCurrentSelectedXcodeDir (xcodeDir) &&
665
+ !StringRef (getDriver ().getSwiftProgramPath ()).starts_with (xcodeDir)) {
666
+
667
+ // 'xcrun -f swiftc'
668
+ SmallString<256 > xcodeExecutableDir;
669
+ if (findXcodeExecutableDir (xcodeExecutableDir)) {
670
+ using namespace llvm ::sys;
671
+
672
+ // '${toolchain}/usr/bin/swift-plugin-server'
673
+ SmallString<256 > xcodePluginServerPath (xcodeExecutableDir);
674
+ path::append (xcodePluginServerPath, " swift-plugin-server" );
675
+ if (fs::can_execute (xcodePluginServerPath)) {
676
+
677
+ // '${toolchain}/usr/lib/swift/host/plugins'
678
+ SmallString<256 > xcodePluginPath (xcodeExecutableDir);
679
+ path::remove_filename (xcodePluginPath); // 'bin'
680
+ path::append (xcodePluginPath, " lib" , " swift" , " host" , " plugins" );
681
+
682
+ // '${toolchain}/usr/local/lib/swift/host/plugins'
683
+ SmallString<256 > xcodeLocalPluginPath (xcodeExecutableDir);
684
+ path::remove_filename (xcodeLocalPluginPath); // 'bin'
685
+ path::append (xcodeLocalPluginPath, " local" );
686
+ path::append (xcodeLocalPluginPath, " lib" , " swift" , " host" , " plugins" );
687
+
688
+ arguments.push_back (" -external-plugin-path" );
689
+ arguments.push_back (inputArgs.MakeArgString (xcodePluginPath + " #" +
690
+ xcodePluginServerPath));
691
+ arguments.push_back (" -external-plugin-path" );
692
+ arguments.push_back (inputArgs.MakeArgString (
693
+ xcodeLocalPluginPath + " #" + xcodePluginServerPath));
694
+ }
695
+ }
696
+ }
697
+ }
698
+
604
699
if (auto sdkVersion = getTargetSDKVersion (getTriple ())) {
605
700
arguments.push_back (" -target-sdk-version" );
606
701
arguments.push_back (inputArgs.MakeArgString (sdkVersion->getAsString ()));
0 commit comments