summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Lorenz <arphaman@gmail.com>2019-04-26 22:40:47 +0000
committerAlex Lorenz <arphaman@gmail.com>2019-04-26 22:40:47 +0000
commit3bf116c1a4f88d6e3f3fd0887453dea3569e0823 (patch)
tree5f1bfaabbd00b17c0cf9499cbf08291a9ab12fb5
parent8504b5f64f47d54c83f66670e804dc70c6112dae (diff)
downloadbcm5719-llvm-3bf116c1a4f88d6e3f3fd0887453dea3569e0823.tar.gz
bcm5719-llvm-3bf116c1a4f88d6e3f3fd0887453dea3569e0823.zip
[driver][macOS] Link libarclite from the default toolchain when clang
is running in a toolchain outside of xcode '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' that should be in the XcodeDefault toolchain instead. The path to the toolchain is inferred from the SDK path if it's specified. https://bugs.swift.org/browse/SR-9972 rdar://49947573 llvm-svn: 359353
-rw-r--r--clang/lib/Driver/ToolChains/Darwin.cpp31
-rw-r--r--clang/test/Driver/arclite-link-external-toolchain.c8
2 files changed, 38 insertions, 1 deletions
diff --git a/clang/lib/Driver/ToolChains/Darwin.cpp b/clang/lib/Driver/ToolChains/Darwin.cpp
index 20ef6a894e4..4e24a8193c6 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 00000000000..2e6f8c10fc2
--- /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
OpenPOWER on IntegriCloud