diff options
-rw-r--r-- | clang/lib/Driver/ToolChains/Darwin.cpp | 31 | ||||
-rw-r--r-- | clang/test/Driver/arclite-link-external-toolchain.c | 8 |
2 files changed, 38 insertions, 1 deletions
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp index 20ef6a8..4e24a81 100644 --- a/clang/lib/Driver/ToolChains/Darwin.cpp +++ b/clang/lib/Driver/ToolChains/Darwin.cpp @@ -893,6 +893,18 @@ void DarwinClang::addClangWarningOptions(ArgStringList &CC1Args) const { } } +/// Take a path that speculatively points into Xcode and return the +/// `XCODE/Contents/Developer` path if it is an Xcode path, or an empty path +/// otherwise. +static StringRef getXcodeDeveloperPath(StringRef PathIntoXcode) { + static constexpr llvm::StringLiteral XcodeAppSuffix( + ".app/Contents/Developer"); + size_t Index = PathIntoXcode.find(XcodeAppSuffix); + if (Index == StringRef::npos) + return ""; + return PathIntoXcode.take_front(Index + XcodeAppSuffix.size()); +} + void DarwinClang::AddLinkARCArgs(const ArgList &Args, ArgStringList &CmdArgs) const { // Avoid linking compatibility stubs on i386 mac. @@ -905,10 +917,27 @@ void DarwinClang::AddLinkARCArgs(const ArgList &Args, runtime.hasSubscripting()) return; - CmdArgs.push_back("-force_load"); SmallString<128> P(getDriver().ClangExecutable); llvm::sys::path::remove_filename(P); // 'clang' llvm::sys::path::remove_filename(P); // 'bin' + + // 'libarclite' usually lives in the same toolchain as 'clang'. However, the + // Swift open source toolchains for macOS distribute Clang without libarclite. + // In that case, to allow the linker to find 'libarclite', we point to the + // 'libarclite' in the XcodeDefault toolchain instead. + if (getXcodeDeveloperPath(P).empty()) { + if (const Arg *A = Args.getLastArg(options::OPT_isysroot)) { + // Try to infer the path to 'libarclite' in the toolchain from the + // specified SDK path. + StringRef XcodePathForSDK = getXcodeDeveloperPath(A->getValue()); + if (!XcodePathForSDK.empty()) { + P = XcodePathForSDK; + llvm::sys::path::append(P, "Toolchains/XcodeDefault.xctoolchain/usr"); + } + } + } + + CmdArgs.push_back("-force_load"); llvm::sys::path::append(P, "lib", "arc", "libarclite_"); // Mash in the platform. if (isTargetWatchOSSimulator()) diff --git a/clang/test/Driver/arclite-link-external-toolchain.c b/clang/test/Driver/arclite-link-external-toolchain.c new file mode 100644 index 0000000..2e6f8c1 --- /dev/null +++ b/clang/test/Driver/arclite-link-external-toolchain.c @@ -0,0 +1,8 @@ +// RUN: rm -rf %t.tmpdir +// RUN: mkdir -p %t.tmpdir/Xcode.app/Contents/Developers/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk +// RUN: %clang -### -target x86_64-apple-macos10.10 -fobjc-link-runtime -lfoo \ +// RUN: -isysroot %t.tmpdir/Xcode.app/Contents/Developers/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk \ +// RUN: %s 2>&1 | FileCheck %s + +// CHECK: -lfoo +// CHECK: .tmpdir/Xcode.app/Contents/Developer/Toolchains/XcodeDefault.xctoolchain/usr/lib/arc/libarclite_macosx.a |