@@ -212,6 +212,61 @@ 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 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+
215270static void addVersionString (const ArgList &inputArgs, ArgStringList &arguments,
216271 llvm::VersionTuple version) {
217272 llvm::SmallString<8 > buf;
@@ -601,6 +656,46 @@ void toolchains::Darwin::addCommonFrontendArgs(
601656 llvm::opt::ArgStringList &arguments) const {
602657 ToolChain::addCommonFrontendArgs (OI, output, inputArgs, arguments);
603658
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+
604699 if (auto sdkVersion = getTargetSDKVersion (getTriple ())) {
605700 arguments.push_back (" -target-sdk-version" );
606701 arguments.push_back (inputArgs.MakeArgString (sdkVersion->getAsString ()));
0 commit comments