Skip to content

Commit 65709c9

Browse files
committed
[clang][Darwin] Prefer the toolchain-provided libc++.dylib if there is one
When libc++ is bootstrapped with clang, the resulting clang uses the just-built libcxx headers from <install>/bin/../include/c++/v1. However, before this patch, clang would still use the system-provided libc++.dylib (usually in the Apple SDK) because it would fail to add the corresponding linker flag to find the just-built libc++. After this patch, Clang will also add `-L <install>/bin/../lib` to the linker search paths, which will allow the just-built libc++.dylib to be found. Fixes #77653 rdar://107060541
1 parent e74b425 commit 65709c9

File tree

3 files changed

+59
-2
lines changed

3 files changed

+59
-2
lines changed

clang/lib/Driver/ToolChains/Darwin.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -426,6 +426,24 @@ void darwin::Linker::AddLinkArgs(Compilation &C, const ArgList &Args,
426426
Args.AddAllArgs(CmdArgs, options::OPT_sub__library);
427427
Args.AddAllArgs(CmdArgs, options::OPT_sub__umbrella);
428428

429+
// Pass -L <toolchain-install>/bin/../lib/ to linker to prioritize the
430+
// toolchain's libc++.dylib over the sysroot-provided one. This matches
431+
// what we do for determining which libc++ headers to use.
432+
//
433+
// If the toolchain does not provide libc++.dylib, we will fall back to the
434+
// normal system search paths for finding libc++.dylib (on Darwin, that would
435+
// be in the SDK so we would find Apple's system libc++ instead of using
436+
// LLVM's).
437+
{
438+
llvm::SmallString<128> InstallBinPath =
439+
llvm::StringRef(D.Dir); // <install>/bin
440+
llvm::SmallString<128> InstallLibPath = InstallBinPath;
441+
llvm::sys::path::append(InstallLibPath, "..",
442+
"lib"); // <install>/bin/../lib
443+
CmdArgs.push_back("-L");
444+
CmdArgs.push_back(C.getArgs().MakeArgString(InstallLibPath));
445+
}
446+
429447
// Give --sysroot= preference, over the Apple specific behavior to also use
430448
// --isysroot as the syslibroot.
431449
// We check `OPT__sysroot_EQ` directly instead of `getSysRoot` to make sure we

clang/test/Driver/darwin-header-search-libcxx.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@
9292
// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1: "-internal-isystem" "[[TOOLCHAIN]]/usr/bin/../include/c++/v1"
9393
// CHECK-LIBCXX-SYSROOT_AND_TOOLCHAIN-1-NOT: "-internal-isystem" "[[SYSROOT]]/usr/include/c++/v1"
9494

95-
// Make sure that using -nostdinc, -nostdinc++ or -nostdlib will drop both the toolchain
95+
// Make sure that using -nostdinc, -nostdinc++ or -nostdlibinc will drop both the toolchain
9696
// C++ include path and the sysroot one.
9797
//
9898
// RUN: %clang -### %s -fsyntax-only 2>&1 \
@@ -116,7 +116,7 @@
116116
// RUN: -isysroot %S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
117117
// RUN: -stdlib=platform \
118118
// RUN: -nostdinc++ \
119-
// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr \
119+
// RUN: | FileCheck -DSYSROOT=%S/Inputs/basic_darwin_sdk_usr_cxx_v1 \
120120
// RUN: -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \
121121
// RUN: --check-prefix=CHECK-LIBCXX-NOSTDINCXX %s
122122
// CHECK-LIBCXX-NOSTDINCXX: "-cc1"
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
// UNSUPPORTED: system-windows
2+
3+
// Tests to check that we pass -L <install>/bin/../lib/ to the linker to prioritize the toolchain's
4+
// libc++.dylib over the system's libc++.dylib on Darwin. This matches the behavior we have for
5+
// header search paths, where we prioritize toolchain headers and then fall back to the sysroot ones.
6+
7+
// Check that we pass the right -L to the linker even when -stdlib=libc++ is not passed.
8+
//
9+
// RUN: %clang -### %s 2>&1 \
10+
// RUN: --target=x86_64-apple-darwin \
11+
// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \
12+
// RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx \
13+
// RUN: --check-prefix=CHECK-1 %s
14+
//
15+
// CHECK-1: "/usr/bin/ld"
16+
// CHECK-1: "-L" "[[TOOLCHAIN]]/usr/bin/../lib"
17+
18+
// Check that we pass the right -L to the linker when -stdlib=libc++ is passed, both in the
19+
// case where there is libc++.dylib in the toolchain and when there isn't.
20+
//
21+
// RUN: %clang -### %s 2>&1 \
22+
// RUN: --target=x86_64-apple-darwin \
23+
// RUN: -stdlib=libc++ \
24+
// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain_no_libcxx/usr/bin \
25+
// RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain_no_libcxx \
26+
// RUN: --check-prefix=CHECK-2 %s
27+
//
28+
// CHECK-2: "/usr/bin/ld"
29+
// CHECK-2: "-L" "[[TOOLCHAIN]]/usr/bin/../lib"
30+
//
31+
// RUN: %clang -### %s 2>&1 \
32+
// RUN: --target=x86_64-apple-darwin \
33+
// RUN: -stdlib=libc++ \
34+
// RUN: -ccc-install-dir %S/Inputs/basic_darwin_toolchain/usr/bin \
35+
// RUN: | FileCheck -DTOOLCHAIN=%S/Inputs/basic_darwin_toolchain \
36+
// RUN: --check-prefix=CHECK-3 %s
37+
//
38+
// CHECK-3: "/usr/bin/ld"
39+
// CHECK-3: "-L" "[[TOOLCHAIN]]/usr/bin/../lib"

0 commit comments

Comments
 (0)