Skip to content

Commit 1212d1b

Browse files
committedSep 18, 2023
[driver] Perform fallback target searches for stdlib
Searching for target-specific standard library header and library paths should perform fallback searches for targets, the same way searching for the runtime libraries does. It's important for the header and library searches to be consistent, otherwise we could end up using mismatched headers and libraries. (See also https://reviews.llvm.org/D146664.) Reviewed By: phosek Differential Revision: https://reviews.llvm.org/D159293
1 parent b1e3cd1 commit 1212d1b

File tree

10 files changed

+58
-25
lines changed

10 files changed

+58
-25
lines changed
 

‎clang/include/clang/Driver/ToolChain.h

+7-2
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,11 @@ class ToolChain {
209209
FileType Type,
210210
bool AddArch) const;
211211

212+
/// Find the target-specific subdirectory for the current target triple under
213+
/// \p BaseDir, doing fallback triple searches as necessary.
214+
/// \return The subdirectory path if it exists.
215+
std::optional<std::string> getTargetSubDirPath(StringRef BaseDir) const;
216+
212217
/// \name Utilities for implementing subclasses.
213218
///@{
214219
static void addSystemInclude(const llvm::opt::ArgList &DriverArgs,
@@ -504,8 +509,8 @@ class ToolChain {
504509
// Returns the target specific runtime path if it exists.
505510
std::optional<std::string> getRuntimePath() const;
506511

507-
// Returns target specific standard library paths.
508-
path_list getStdlibPaths() const;
512+
// Returns target specific standard library path if it exists.
513+
std::optional<std::string> getStdlibPath() const;
509514

510515
// Returns <ResourceDir>/lib/<OSName>/<arch> or <ResourceDir>/lib/<triple>.
511516
// This is used by runtimes (such as OpenMP) to find arch-specific libraries.

‎clang/lib/Driver/ToolChain.cpp

+16-12
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ ToolChain::ToolChain(const Driver &D, const llvm::Triple &T,
8888

8989
if (std::optional<std::string> Path = getRuntimePath())
9090
getLibraryPaths().push_back(*Path);
91-
for (const auto &Path : getStdlibPaths())
92-
addIfExists(getFilePaths(), Path);
91+
if (std::optional<std::string> Path = getStdlibPath())
92+
getFilePaths().push_back(*Path);
9393
for (const auto &Path : getArchSpecificLibPaths())
9494
addIfExists(getFilePaths(), Path);
9595
}
@@ -677,11 +677,12 @@ const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args,
677677
return Args.MakeArgString(getCompilerRT(Args, Component, Type));
678678
}
679679

680-
std::optional<std::string> ToolChain::getRuntimePath() const {
680+
std::optional<std::string>
681+
ToolChain::getTargetSubDirPath(StringRef BaseDir) const {
681682
auto getPathForTriple =
682-
[this](const llvm::Triple &Triple) -> std::optional<std::string> {
683-
SmallString<128> P(D.ResourceDir);
684-
llvm::sys::path::append(P, "lib", Triple.str());
683+
[&](const llvm::Triple &Triple) -> std::optional<std::string> {
684+
SmallString<128> P(BaseDir);
685+
llvm::sys::path::append(P, Triple.str());
685686
if (getVFS().exists(P))
686687
return std::string(P);
687688
return {};
@@ -725,13 +726,16 @@ std::optional<std::string> ToolChain::getRuntimePath() const {
725726
return {};
726727
}
727728

728-
ToolChain::path_list ToolChain::getStdlibPaths() const {
729-
path_list Paths;
730-
SmallString<128> P(D.Dir);
731-
llvm::sys::path::append(P, "..", "lib", getTripleString());
732-
Paths.push_back(std::string(P.str()));
729+
std::optional<std::string> ToolChain::getRuntimePath() const {
730+
SmallString<128> P(D.ResourceDir);
731+
llvm::sys::path::append(P, "lib");
732+
return getTargetSubDirPath(P);
733+
}
733734

734-
return Paths;
735+
std::optional<std::string> ToolChain::getStdlibPath() const {
736+
SmallString<128> P(D.Dir);
737+
llvm::sys::path::append(P, "..", "lib");
738+
return getTargetSubDirPath(P);
735739
}
736740

737741
ToolChain::path_list ToolChain::getArchSpecificLibPaths() const {

‎clang/lib/Driver/ToolChains/Fuchsia.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -257,8 +257,8 @@ Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple,
257257

258258
auto FilePaths = [&](const Multilib &M) -> std::vector<std::string> {
259259
std::vector<std::string> FP;
260-
for (const std::string &Path : getStdlibPaths()) {
261-
SmallString<128> P(Path);
260+
if (std::optional<std::string> Path = getStdlibPath()) {
261+
SmallString<128> P(*Path);
262262
llvm::sys::path::append(P, M.gccSuffix());
263263
FP.push_back(std::string(P.str()));
264264
}

‎clang/lib/Driver/ToolChains/Gnu.cpp

+11-6
Original file line numberDiff line numberDiff line change
@@ -3100,19 +3100,24 @@ Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
31003100
llvm::opt::ArgStringList &CC1Args) const {
31013101
const Driver &D = getDriver();
31023102
std::string SysRoot = computeSysRoot();
3103-
std::string Target = getTripleString();
31043103

31053104
auto AddIncludePath = [&](StringRef Path, bool TargetDirRequired = false) {
31063105
std::string Version = detectLibcxxVersion(Path);
31073106
if (Version.empty())
31083107
return false;
31093108

31103109
// First add the per-target include path if it exists.
3111-
SmallString<128> TargetDir(Path);
3112-
llvm::sys::path::append(TargetDir, Target, "c++", Version);
3113-
if (D.getVFS().exists(TargetDir))
3114-
addSystemInclude(DriverArgs, CC1Args, TargetDir);
3115-
else if (TargetDirRequired)
3110+
bool TargetDirExists = false;
3111+
std::optional<std::string> TargetIncludeDir = getTargetSubDirPath(Path);
3112+
if (TargetIncludeDir) {
3113+
SmallString<128> TargetDir(*TargetIncludeDir);
3114+
llvm::sys::path::append(TargetDir, "c++", Version);
3115+
if (D.getVFS().exists(TargetDir)) {
3116+
addSystemInclude(DriverArgs, CC1Args, TargetDir);
3117+
TargetDirExists = true;
3118+
}
3119+
}
3120+
if (TargetDirRequired && !TargetDirExists)
31163121
return false;
31173122

31183123
// Second add the generic one.

‎clang/lib/Driver/ToolChains/VEToolchain.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,11 @@ VEToolChain::VEToolChain(const Driver &D, const llvm::Triple &Triple,
4545
getFilePaths().clear();
4646

4747
// Add library directories:
48-
// ${BINPATH}/../lib/ve-unknown-linux-gnu, (== getStdlibPaths)
48+
// ${BINPATH}/../lib/ve-unknown-linux-gnu, (== getStdlibPath)
4949
// ${RESOURCEDIR}/lib/linux/ve, (== getArchSpecificLibPaths)
5050
// ${SYSROOT}/opt/nec/ve/lib,
51-
for (auto &Path : getStdlibPaths())
52-
getFilePaths().push_back(std::move(Path));
51+
if (std::optional<std::string> Path = getStdlibPath())
52+
getFilePaths().push_back(std::move(*Path));
5353
for (const auto &Path : getArchSpecificLibPaths())
5454
getFilePaths().push_back(Path);
5555
getFilePaths().push_back(computeSysRoot() + "/opt/nec/ve/lib");

‎clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/bin/.keep

Whitespace-only changes.

‎clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/lib/aarch64-unknown-linux-android/libc++.so

Whitespace-only changes.

‎clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/lib/aarch64-unknown-linux-android21/libc++.so

Whitespace-only changes.

‎clang/test/Driver/android-installed-libcxx.cpp

+4
Original file line numberDiff line numberDiff line change
@@ -18,5 +18,9 @@
1818
// RUN: --sysroot=%t2/sysroot -stdlib=libc++ -fsyntax-only \
1919
// RUN: %s -### 2>&1 | FileCheck --check-prefix=ANDROID-DIR -DDIR=%/t2/bin %s
2020

21+
// RUN: %clang -target aarch64-none-linux-android21 -ccc-install-dir %/t2/bin \
22+
// RUN: --sysroot=%t2/sysroot -stdlib=libc++ -fsyntax-only \
23+
// RUN: %s -### 2>&1 | FileCheck --check-prefix=ANDROID-DIR -DDIR=%/t2/bin %s
24+
2125
// ANDROID-DIR: "-internal-isystem" "[[DIR]][[SEP:/|\\\\]]..[[SEP]]include[[SEP]]aarch64-none-linux-android[[SEP]]c++[[SEP]]v1"
2226
// ANDROID-DIR-SAME: "-internal-isystem" "[[DIR]][[SEP]]..[[SEP]]include[[SEP]]c++[[SEP]]v1"

‎clang/test/Driver/linux-per-target-runtime-dir.c

+15
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,21 @@
1414
// CHECK-PER-TARGET-RUNTIME: "--sysroot=[[SYSROOT]]"
1515
// CHECK-PER-TARGET-RUNTIME: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-linux-gnu"
1616

17+
// RUN: %clang --target=aarch64-unknown-linux-android21 -print-file-name=libc++.so 2>&1 \
18+
// RUN: -ccc-install-dir %S/Inputs/basic_android_libcxx_tree/usr/bin \
19+
// RUN: | FileCheck --check-prefix=CHECK-LIBCXX-ANDROID21 %s
20+
// CHECK-LIBCXX-ANDROID21: ..{{/|\\}}lib{{/|\\}}aarch64-unknown-linux-android21{{/|\\}}libc++.so
21+
22+
// RUN: %clang --target=aarch64-unknown-linux-android23 -print-file-name=libc++.so 2>&1 \
23+
// RUN: -ccc-install-dir %S/Inputs/basic_android_libcxx_tree/usr/bin \
24+
// RUN: | FileCheck --check-prefix=CHECK-LIBCXX-ANDROID23 %s
25+
// CHECK-LIBCXX-ANDROID23: ..{{/|\\}}lib{{/|\\}}aarch64-unknown-linux-android{{/|\\}}libc++.so
26+
27+
// RUN: %clang --target=aarch64-unknown-linux-android -print-file-name=libc++.so 2>&1 \
28+
// RUN: -ccc-install-dir %S/Inputs/basic_android_libcxx_tree/usr/bin \
29+
// RUN: | FileCheck --check-prefix=CHECK-LIBCXX-ANDROID %s
30+
// CHECK-LIBCXX-ANDROID: ..{{/|\\}}lib{{/|\\}}aarch64-unknown-linux-android{{/|\\}}libc++.so
31+
1732
// RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name 2>&1 \
1833
// RUN: --target=x86_64-unknown-linux-gnu \
1934
// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \

0 commit comments

Comments
 (0)