diff --git a/clang/include/clang/Driver/ToolChain.h b/clang/include/clang/Driver/ToolChain.h index 0b38b939a188ae..96d76c2384a9aa 100644 --- a/clang/include/clang/Driver/ToolChain.h +++ b/clang/include/clang/Driver/ToolChain.h @@ -209,6 +209,11 @@ class ToolChain { FileType Type, bool AddArch) const; + /// Find the target-specific subdirectory for the current target triple under + /// \p BaseDir, doing fallback triple searches as necessary. + /// \return The subdirectory path if it exists. + std::optional getTargetSubDirPath(StringRef BaseDir) const; + /// \name Utilities for implementing subclasses. ///@{ static void addSystemInclude(const llvm::opt::ArgList &DriverArgs, @@ -504,8 +509,8 @@ class ToolChain { // Returns the target specific runtime path if it exists. std::optional getRuntimePath() const; - // Returns target specific standard library paths. - path_list getStdlibPaths() const; + // Returns target specific standard library path if it exists. + std::optional getStdlibPath() const; // Returns /lib// or /lib/. // This is used by runtimes (such as OpenMP) to find arch-specific libraries. diff --git a/clang/lib/Driver/ToolChain.cpp b/clang/lib/Driver/ToolChain.cpp index 410757d5f9e184..3a7e90e6b63770 100644 --- a/clang/lib/Driver/ToolChain.cpp +++ b/clang/lib/Driver/ToolChain.cpp @@ -88,8 +88,8 @@ ToolChain::ToolChain(const Driver &D, const llvm::Triple &T, if (std::optional Path = getRuntimePath()) getLibraryPaths().push_back(*Path); - for (const auto &Path : getStdlibPaths()) - addIfExists(getFilePaths(), Path); + if (std::optional Path = getStdlibPath()) + getFilePaths().push_back(*Path); for (const auto &Path : getArchSpecificLibPaths()) addIfExists(getFilePaths(), Path); } @@ -677,11 +677,12 @@ const char *ToolChain::getCompilerRTArgString(const llvm::opt::ArgList &Args, return Args.MakeArgString(getCompilerRT(Args, Component, Type)); } -std::optional ToolChain::getRuntimePath() const { +std::optional +ToolChain::getTargetSubDirPath(StringRef BaseDir) const { auto getPathForTriple = - [this](const llvm::Triple &Triple) -> std::optional { - SmallString<128> P(D.ResourceDir); - llvm::sys::path::append(P, "lib", Triple.str()); + [&](const llvm::Triple &Triple) -> std::optional { + SmallString<128> P(BaseDir); + llvm::sys::path::append(P, Triple.str()); if (getVFS().exists(P)) return std::string(P); return {}; @@ -725,13 +726,16 @@ std::optional ToolChain::getRuntimePath() const { return {}; } -ToolChain::path_list ToolChain::getStdlibPaths() const { - path_list Paths; - SmallString<128> P(D.Dir); - llvm::sys::path::append(P, "..", "lib", getTripleString()); - Paths.push_back(std::string(P.str())); +std::optional ToolChain::getRuntimePath() const { + SmallString<128> P(D.ResourceDir); + llvm::sys::path::append(P, "lib"); + return getTargetSubDirPath(P); +} - return Paths; +std::optional ToolChain::getStdlibPath() const { + SmallString<128> P(D.Dir); + llvm::sys::path::append(P, "..", "lib"); + return getTargetSubDirPath(P); } ToolChain::path_list ToolChain::getArchSpecificLibPaths() const { diff --git a/clang/lib/Driver/ToolChains/Fuchsia.cpp b/clang/lib/Driver/ToolChains/Fuchsia.cpp index af34a46ae4f7d6..55c966ff39cd45 100644 --- a/clang/lib/Driver/ToolChains/Fuchsia.cpp +++ b/clang/lib/Driver/ToolChains/Fuchsia.cpp @@ -257,8 +257,8 @@ Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple, auto FilePaths = [&](const Multilib &M) -> std::vector { std::vector FP; - for (const std::string &Path : getStdlibPaths()) { - SmallString<128> P(Path); + if (std::optional Path = getStdlibPath()) { + SmallString<128> P(*Path); llvm::sys::path::append(P, M.gccSuffix()); FP.push_back(std::string(P.str())); } diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp index 350349c1d31fda..fe7219889926ea 100644 --- a/clang/lib/Driver/ToolChains/Gnu.cpp +++ b/clang/lib/Driver/ToolChains/Gnu.cpp @@ -3096,7 +3096,6 @@ Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const { const Driver &D = getDriver(); std::string SysRoot = computeSysRoot(); - std::string Target = getTripleString(); auto AddIncludePath = [&](StringRef Path, bool TargetDirRequired = false) { std::string Version = detectLibcxxVersion(Path); @@ -3104,11 +3103,17 @@ Generic_GCC::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, return false; // First add the per-target include path if it exists. - SmallString<128> TargetDir(Path); - llvm::sys::path::append(TargetDir, Target, "c++", Version); - if (D.getVFS().exists(TargetDir)) - addSystemInclude(DriverArgs, CC1Args, TargetDir); - else if (TargetDirRequired) + bool TargetDirExists = false; + std::optional TargetIncludeDir = getTargetSubDirPath(Path); + if (TargetIncludeDir) { + SmallString<128> TargetDir(*TargetIncludeDir); + llvm::sys::path::append(TargetDir, "c++", Version); + if (D.getVFS().exists(TargetDir)) { + addSystemInclude(DriverArgs, CC1Args, TargetDir); + TargetDirExists = true; + } + } + if (TargetDirRequired && !TargetDirExists) return false; // Second add the generic one. diff --git a/clang/lib/Driver/ToolChains/VEToolchain.cpp b/clang/lib/Driver/ToolChains/VEToolchain.cpp index e72db208f587be..71b6fe2ea3619c 100644 --- a/clang/lib/Driver/ToolChains/VEToolchain.cpp +++ b/clang/lib/Driver/ToolChains/VEToolchain.cpp @@ -45,11 +45,11 @@ VEToolChain::VEToolChain(const Driver &D, const llvm::Triple &Triple, getFilePaths().clear(); // Add library directories: - // ${BINPATH}/../lib/ve-unknown-linux-gnu, (== getStdlibPaths) + // ${BINPATH}/../lib/ve-unknown-linux-gnu, (== getStdlibPath) // ${RESOURCEDIR}/lib/linux/ve, (== getArchSpecificLibPaths) // ${SYSROOT}/opt/nec/ve/lib, - for (auto &Path : getStdlibPaths()) - getFilePaths().push_back(std::move(Path)); + if (std::optional Path = getStdlibPath()) + getFilePaths().push_back(std::move(*Path)); for (const auto &Path : getArchSpecificLibPaths()) getFilePaths().push_back(Path); getFilePaths().push_back(computeSysRoot() + "/opt/nec/ve/lib"); diff --git a/clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/bin/.keep b/clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/bin/.keep new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/lib/aarch64-unknown-linux-android/libc++.so b/clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/lib/aarch64-unknown-linux-android/libc++.so new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/lib/aarch64-unknown-linux-android21/libc++.so b/clang/test/Driver/Inputs/basic_android_libcxx_tree/usr/lib/aarch64-unknown-linux-android21/libc++.so new file mode 100644 index 00000000000000..e69de29bb2d1d6 diff --git a/clang/test/Driver/android-installed-libcxx.cpp b/clang/test/Driver/android-installed-libcxx.cpp index 60fa49c2b17bbb..4d139a1fb3693e 100644 --- a/clang/test/Driver/android-installed-libcxx.cpp +++ b/clang/test/Driver/android-installed-libcxx.cpp @@ -18,5 +18,9 @@ // RUN: --sysroot=%t2/sysroot -stdlib=libc++ -fsyntax-only \ // RUN: %s -### 2>&1 | FileCheck --check-prefix=ANDROID-DIR -DDIR=%/t2/bin %s +// RUN: %clang -target aarch64-none-linux-android21 -ccc-install-dir %/t2/bin \ +// RUN: --sysroot=%t2/sysroot -stdlib=libc++ -fsyntax-only \ +// RUN: %s -### 2>&1 | FileCheck --check-prefix=ANDROID-DIR -DDIR=%/t2/bin %s + // ANDROID-DIR: "-internal-isystem" "[[DIR]][[SEP:/|\\\\]]..[[SEP]]include[[SEP]]aarch64-none-linux-android[[SEP]]c++[[SEP]]v1" // ANDROID-DIR-SAME: "-internal-isystem" "[[DIR]][[SEP]]..[[SEP]]include[[SEP]]c++[[SEP]]v1" diff --git a/clang/test/Driver/linux-per-target-runtime-dir.c b/clang/test/Driver/linux-per-target-runtime-dir.c index a38e0e56035c6d..c5c871236044b2 100644 --- a/clang/test/Driver/linux-per-target-runtime-dir.c +++ b/clang/test/Driver/linux-per-target-runtime-dir.c @@ -14,6 +14,21 @@ // CHECK-PER-TARGET-RUNTIME: "--sysroot=[[SYSROOT]]" // CHECK-PER-TARGET-RUNTIME: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-unknown-linux-gnu" +// RUN: %clang --target=aarch64-unknown-linux-android21 -print-file-name=libc++.so 2>&1 \ +// RUN: -ccc-install-dir %S/Inputs/basic_android_libcxx_tree/usr/bin \ +// RUN: | FileCheck --check-prefix=CHECK-LIBCXX-ANDROID21 %s +// CHECK-LIBCXX-ANDROID21: ..{{/|\\}}lib{{/|\\}}aarch64-unknown-linux-android21{{/|\\}}libc++.so + +// RUN: %clang --target=aarch64-unknown-linux-android23 -print-file-name=libc++.so 2>&1 \ +// RUN: -ccc-install-dir %S/Inputs/basic_android_libcxx_tree/usr/bin \ +// RUN: | FileCheck --check-prefix=CHECK-LIBCXX-ANDROID23 %s +// CHECK-LIBCXX-ANDROID23: ..{{/|\\}}lib{{/|\\}}aarch64-unknown-linux-android{{/|\\}}libc++.so + +// RUN: %clang --target=aarch64-unknown-linux-android -print-file-name=libc++.so 2>&1 \ +// RUN: -ccc-install-dir %S/Inputs/basic_android_libcxx_tree/usr/bin \ +// RUN: | FileCheck --check-prefix=CHECK-LIBCXX-ANDROID %s +// CHECK-LIBCXX-ANDROID: ..{{/|\\}}lib{{/|\\}}aarch64-unknown-linux-android{{/|\\}}libc++.so + // RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name 2>&1 \ // RUN: --target=x86_64-unknown-linux-gnu \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \