Index: clang/include/clang/Driver/ToolChain.h =================================================================== --- clang/include/clang/Driver/ToolChain.h +++ clang/include/clang/Driver/ToolChain.h @@ -492,9 +492,9 @@ // Returns target specific standard library paths. path_list getStdlibPaths() const; - // Returns /lib//. This is used by runtimes (such - // as OpenMP) to find arch-specific libraries. - virtual std::string getArchSpecificLibPath() const; + // Returns /lib// or /lib/. + // This is used by runtimes (such as OpenMP) to find arch-specific libraries. + virtual path_list getArchSpecificLibPaths() const; // Returns part of above. virtual StringRef getOSLibName() const; Index: clang/lib/Driver/ToolChain.cpp =================================================================== --- clang/lib/Driver/ToolChain.cpp +++ clang/lib/Driver/ToolChain.cpp @@ -86,7 +86,8 @@ addIfExists(getLibraryPaths(), Path); for (const auto &Path : getStdlibPaths()) addIfExists(getFilePaths(), Path); - addIfExists(getFilePaths(), getArchSpecificLibPath()); + for (const auto &Path : getArchSpecificLibPaths()) + addIfExists(getFilePaths(), Path); } llvm::Expected> @@ -621,11 +622,21 @@ return Paths; } -std::string ToolChain::getArchSpecificLibPath() const { - SmallString<128> Path(getDriver().ResourceDir); - llvm::sys::path::append(Path, "lib", getOSLibName(), - llvm::Triple::getArchTypeName(getArch())); - return std::string(Path.str()); +ToolChain::path_list ToolChain::getArchSpecificLibPaths() const { + path_list Paths; + + auto AddPath = [&](const ArrayRef &SS) { + SmallString<128> Path(getDriver().ResourceDir); + llvm::sys::path::append(Path, "lib"); + for (auto &S : SS) + llvm::sys::path::append(Path, S); + Paths.push_back(std::string(Path.str())); + }; + + AddPath({getTriple().str()}); + AddPath({getOSLibName(), llvm::Triple::getArchTypeName(getArch())}); + + return Paths; } bool ToolChain::needsProfileRT(const ArgList &Args) { Index: clang/lib/Driver/ToolChains/CommonArgs.cpp =================================================================== --- clang/lib/Driver/ToolChains/CommonArgs.cpp +++ clang/lib/Driver/ToolChains/CommonArgs.cpp @@ -815,10 +815,11 @@ options::OPT_fno_rtlib_add_rpath, DefaultValue)) return; - std::string CandidateRPath = TC.getArchSpecificLibPath(); - if (TC.getVFS().exists(CandidateRPath)) { - CmdArgs.push_back("-rpath"); - CmdArgs.push_back(Args.MakeArgString(CandidateRPath)); + for (const auto &CandidateRPath : TC.getArchSpecificLibPaths()) { + if (TC.getVFS().exists(CandidateRPath)) { + CmdArgs.push_back("-rpath"); + CmdArgs.push_back(Args.MakeArgString(CandidateRPath)); + } } } Index: clang/lib/Driver/ToolChains/OHOS.h =================================================================== --- clang/lib/Driver/ToolChains/OHOS.h +++ clang/lib/Driver/ToolChains/OHOS.h @@ -82,7 +82,8 @@ SanitizerMask getSupportedSanitizers() const override; void addProfileRTLibs(const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs) const override; - std::string getArchSpecificLibPath() const override; + path_list getArchSpecificLibPaths() const override; + private: Multilib SelectedMultilib; }; Index: clang/lib/Driver/ToolChains/OHOS.cpp =================================================================== --- clang/lib/Driver/ToolChains/OHOS.cpp +++ clang/lib/Driver/ToolChains/OHOS.cpp @@ -139,9 +139,9 @@ SelectedMultilib = Result.SelectedMultilib; getFilePaths().clear(); - std::string CandidateLibPath = getArchSpecificLibPath(); - if (getVFS().exists(CandidateLibPath)) - getFilePaths().push_back(CandidateLibPath); + for (const auto &CandidateLibPath : getArchSpecificLibPaths()) + if (getVFS().exists(CandidateLibPath)) + getFilePaths().push_back(CandidateLibPath); getLibraryPaths().clear(); for (auto &Path : getRuntimePaths()) @@ -401,9 +401,12 @@ ToolChain::addProfileRTLibs(Args, CmdArgs); } -std::string OHOS::getArchSpecificLibPath() const { +ToolChain::path_list OHOS::getArchSpecificLibPaths() const { + ToolChain::path_list Paths; llvm::Triple Triple = getTriple(); - return makePath({getDriver().ResourceDir, "lib", getMultiarchTriple(Triple)}); + Paths.push_back( + makePath({getDriver().ResourceDir, "lib", getMultiarchTriple(Triple)})); + return Paths; } ToolChain::UnwindLibType OHOS::GetUnwindLibType(const llvm::opt::ArgList &Args) const { Index: clang/lib/Driver/ToolChains/VEToolchain.cpp =================================================================== --- clang/lib/Driver/ToolChains/VEToolchain.cpp +++ clang/lib/Driver/ToolChains/VEToolchain.cpp @@ -33,7 +33,7 @@ // These are OK. // Default file paths are following: - // ${RESOURCEDIR}/lib/linux/ve, (== getArchSpecificLibPath) + // ${RESOURCEDIR}/lib/linux/ve, (== getArchSpecificLibPaths) // /lib/../lib64, // /usr/lib/../lib64, // ${BINPATH}/../lib, @@ -45,12 +45,13 @@ getFilePaths().clear(); // Add library directories: - // ${BINPATH}/../lib/ve-unknown-linux-gnu, (== getStdlibPath) - // ${RESOURCEDIR}/lib/linux/ve, (== getArchSpecificLibPath) + // ${BINPATH}/../lib/ve-unknown-linux-gnu, (== getStdlibPaths) + // ${RESOURCEDIR}/lib/linux/ve, (== getArchSpecificLibPaths) // ${SYSROOT}/opt/nec/ve/lib, for (auto &Path : getStdlibPaths()) getFilePaths().push_back(std::move(Path)); - getFilePaths().push_back(getArchSpecificLibPath()); + for (const auto &Path : getArchSpecificLibPaths()) + getFilePaths().push_back(Path); getFilePaths().push_back(computeSysRoot() + "/opt/nec/ve/lib"); } Index: clang/test/Driver/arch-specific-libdir-rpath.c =================================================================== --- clang/test/Driver/arch-specific-libdir-rpath.c +++ clang/test/Driver/arch-specific-libdir-rpath.c @@ -75,6 +75,15 @@ // RUN: -frtlib-add-rpath \ // RUN: | FileCheck --check-prefixes=RESDIR,NO-LIBPATH,NO-RPATH %s +// Test that the driver adds an per-target arch-specific subdirectory in +// {RESOURCE_DIR}/lib/{triple} to the linker search path and to '-rpath' +// +// RUN: %clang %s -### 2>&1 --target=x86_64-linux-gnu \ +// RUN: -fsanitize=address -shared-libasan \ +// RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ +// RUN: -frtlib-add-rpath \ +// RUN: | FileCheck --check-prefixes=PERTARGET %s + // RESDIR: "-resource-dir" "[[RESDIR:[^"]*]]" // // LIBPATH-X86_64: -L[[RESDIR]]{{(/|\\\\)lib(/|\\\\)linux(/|\\\\)x86_64}} @@ -88,3 +97,7 @@ // // NO-LIBPATH-NOT: "-L{{[^"]*Inputs(/|\\\\)resource_dir}}" // NO-RPATH-NOT: "-rpath" {{.*(/|\\\\)Inputs(/|\\\\)resource_dir}} + +// PERTARGET: "-resource-dir" "[[PTRESDIR:[^"]*]]" +// PERTARGET: -L[[PTRESDIR]]{{(/|\\\\)lib(/|\\\\)x86_64-unknown-linux-gnu}} +// PERTARGET: "-rpath" "[[PTRESDIR]]{{(/|\\\\)lib(/|\\\\)x86_64-unknown-linux-gnu}}"