Index: include/clang/Driver/ToolChain.h =================================================================== --- include/clang/Driver/ToolChain.h +++ include/clang/Driver/ToolChain.h @@ -389,6 +389,12 @@ getCompilerRTArgString(const llvm::opt::ArgList &Args, StringRef Component, FileType Type = ToolChain::FT_Static) const; + // Returns target specific runtime path if it exists. + virtual Optional getRuntimePath() const; + + // Returns target specific C++ library path if it exists. + virtual Optional getCXXStdlibPath() const; + // Returns /lib//. This is used by runtimes (such // as OpenMP) to find arch-specific libraries. std::string getArchSpecificLibPath() const; Index: lib/Driver/ToolChain.cpp =================================================================== --- lib/Driver/ToolChain.cpp +++ lib/Driver/ToolChain.cpp @@ -73,29 +73,13 @@ const ArgList &Args) : D(D), Triple(T), Args(Args), CachedRTTIArg(GetRTTIArgument(Args)), CachedRTTIMode(CalculateRTTIMode(Args, Triple, CachedRTTIArg)) { - SmallString<128> P; - if (D.CCCIsCXX()) { - P.assign(D.Dir); - llvm::sys::path::append(P, "..", "lib", D.getTargetTriple(), "c++"); - if (getVFS().exists(P)) - getLibraryPaths().push_back(P.str()); - - P.assign(D.Dir); - llvm::sys::path::append(P, "..", "lib", Triple.str(), "c++"); - if (getVFS().exists(P)) - getLibraryPaths().push_back(P.str()); + if (auto CXXStdlibPath = getCXXStdlibPath()) + getFilePaths().push_back(*CXXStdlibPath); } - P.assign(D.ResourceDir); - llvm::sys::path::append(P, D.getTargetTriple(), "lib"); - if (getVFS().exists(P)) - getLibraryPaths().push_back(P.str()); - - P.assign(D.ResourceDir); - llvm::sys::path::append(P, Triple.str(), "lib"); - if (getVFS().exists(P)) - getLibraryPaths().push_back(P.str()); + if (auto RuntimePath = getRuntimePath()) + getLibraryPaths().push_back(*RuntimePath); std::string CandidateLibPath = getArchSpecificLibPath(); if (getVFS().exists(CandidateLibPath)) @@ -421,6 +405,43 @@ return Args.MakeArgString(getCompilerRT(Args, Component, Type)); } + +Optional ToolChain::getRuntimePath() const { + SmallString<128> P; + + // First try the triple passed to driver as --target=. + P.assign(D.ResourceDir); + llvm::sys::path::append(P, D.getTargetTriple(), "lib"); + if (getVFS().exists(P)) + return llvm::Optional(P.str()); + + // Second try the normalized triple. + P.assign(D.ResourceDir); + llvm::sys::path::append(P, Triple.str(), "lib"); + if (getVFS().exists(P)) + return llvm::Optional(P.str()); + + return None; +} + +Optional ToolChain::getCXXStdlibPath() const { + SmallString<128> P; + + // First try the triple passed to driver as --target=. + P.assign(D.Dir); + llvm::sys::path::append(P, "..", "lib", D.getTargetTriple(), "c++"); + if (getVFS().exists(P)) + return llvm::Optional(P.str()); + + // Second try the normalized triple. + P.assign(D.Dir); + llvm::sys::path::append(P, "..", "lib", Triple.str(), "c++"); + if (getVFS().exists(P)) + return llvm::Optional(P.str()); + + return None; +} + std::string ToolChain::getArchSpecificLibPath() const { SmallString<128> Path(getDriver().ResourceDir); llvm::sys::path::append(Path, "lib", getOSLibName(), @@ -833,10 +854,6 @@ void ToolChain::AddFilePathLibArgs(const ArgList &Args, ArgStringList &CmdArgs) const { - for (const auto &LibPath : getLibraryPaths()) - if(LibPath.length() > 0) - CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath)); - for (const auto &LibPath : getFilePaths()) if(LibPath.length() > 0) CmdArgs.push_back(Args.MakeArgString(StringRef("-L") + LibPath)); Index: lib/Driver/ToolChains/Fuchsia.cpp =================================================================== --- lib/Driver/ToolChains/Fuchsia.cpp +++ lib/Driver/ToolChains/Fuchsia.cpp @@ -172,21 +172,16 @@ getFilePaths().push_back(P.str()); } - auto RuntimeDirs = [&](const Multilib &M) -> std::vector { - SmallString<128> P; - std::vector RD; - - P.assign(D.ResourceDir); - llvm::sys::path::append(P, D.getTargetTriple(), "lib", M.gccSuffix()); - if (getVFS().exists(P)) - RD.push_back(P.str()); - - P.assign(D.ResourceDir); - llvm::sys::path::append(P, Triple.str(), "lib", M.gccSuffix()); - if (getVFS().exists(P)) - RD.push_back(P.str()); - - return RD; + auto FilePaths = [&](const Multilib &M) -> std::vector { + std::vector FP; + if (D.CCCIsCXX()) { + if (auto CXXStdlibPath = getCXXStdlibPath()) { + SmallString<128> P(*CXXStdlibPath); + llvm::sys::path::append(P, M.gccSuffix()); + FP.push_back(P.str()); + } + } + return FP; }; Multilibs.push_back(Multilib()); @@ -198,7 +193,7 @@ Multilibs.push_back(Multilib("asan", {}, {}, 2) .flag("+fsanitize=address")); Multilibs.FilterOut([&](const Multilib &M) { - std::vector RD = RuntimeDirs(M); + std::vector RD = FilePaths(M); return std::all_of(RD.begin(), RD.end(), [&](std::string P) { return !getVFS().exists(P); }); @@ -209,14 +204,14 @@ Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, true), "fexceptions", Flags); addMultilibFlag(getSanitizerArgs().needsAsanRt(), "fsanitize=address", Flags); - Multilibs.setFilePathsCallback(RuntimeDirs); + Multilibs.setFilePathsCallback(FilePaths); if (Multilibs.select(Flags, SelectedMultilib)) if (!SelectedMultilib.isDefault()) if (const auto &PathsCallback = Multilibs.filePathsCallback()) for (const auto &Path : PathsCallback(SelectedMultilib)) - // We need to prepend the multilib path to ensure it takes precedence. - getLibraryPaths().insert(getLibraryPaths().begin(), Path); + // Prepend the multilib path to ensure it takes the precedence. + getFilePaths().insert(getFilePaths().begin(), Path); } std::string Fuchsia::ComputeEffectiveClangTriple(const ArgList &Args, Index: test/Driver/fuchsia.c =================================================================== --- test/Driver/fuchsia.c +++ test/Driver/fuchsia.c @@ -93,8 +93,6 @@ // CHECK-ASAN-X86: "-fsanitize=address" // CHECK-ASAN-X86: "-fsanitize-address-globals-dead-stripping" // CHECK-ASAN-X86: "-dynamic-linker" "asan/ld.so.1" -// CHECK-ASAN-X86: "-L[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib{{/|\\\\}}asan" -// CHECK-ASAN-X86: "-L[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib" // CHECK-ASAN-X86: "[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib{{/|\\\\}}libclang_rt.asan.so" // CHECK-ASAN-X86: "[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib{{/|\\\\}}libclang_rt.asan-preinit.a" @@ -107,8 +105,6 @@ // CHECK-ASAN-AARCH64: "-fsanitize=address" // CHECK-ASAN-AARCH64: "-fsanitize-address-globals-dead-stripping" // CHECK-ASAN-AARCH64: "-dynamic-linker" "asan/ld.so.1" -// CHECK-ASAN-AARCH64: "-L[[RESOURCE_DIR]]{{/|\\\\}}aarch64-fuchsia{{/|\\\\}}lib{{/|\\\\}}asan" -// CHECK-ASAN-AARCH64: "-L[[RESOURCE_DIR]]{{/|\\\\}}aarch64-fuchsia{{/|\\\\}}lib" // CHECK-ASAN-AARCH64: "[[RESOURCE_DIR]]{{/|\\\\}}aarch64-fuchsia{{/|\\\\}}lib{{/|\\\\}}libclang_rt.asan.so" // CHECK-ASAN-AARCH64: "[[RESOURCE_DIR]]{{/|\\\\}}aarch64-fuchsia{{/|\\\\}}lib{{/|\\\\}}libclang_rt.asan-preinit.a" Index: test/Driver/fuchsia.cpp =================================================================== --- test/Driver/fuchsia.cpp +++ test/Driver/fuchsia.cpp @@ -1,4 +1,5 @@ // RUN: %clangxx %s -### -no-canonical-prefixes --target=x86_64-fuchsia \ +// RUN: -ccc-install-dir %S/Inputs/basic_fuchsia_tree/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ // RUN: --sysroot=%S/platform -fuse-ld=lld 2>&1 | FileCheck %s // CHECK: {{.*}}clang{{.*}}" "-cc1" @@ -44,29 +45,33 @@ // CHECK-STATIC: "--pop-state" // CHECK-STATIC: "-lc" -// RUN: %clang %s -### --target=x86_64-fuchsia -nostdlib++ -fuse-ld=lld 2>&1 \ +// RUN: %clangxx %s -### --target=x86_64-fuchsia -nostdlib++ -fuse-ld=lld 2>&1 \ // RUN: | FileCheck %s -check-prefix=CHECK-NOSTDLIBXX // CHECK-NOSTDLIBXX-NOT: "-lc++" // CHECK-NOSTDLIBXX-NOT: "-lm" // CHECK-NOSTDLIBXX: "-lc" -// RUN: %clang %s -### --target=x86_64-fuchsia \ +// RUN: %clangxx %s -### --target=x86_64-fuchsia \ +// RUN: -ccc-install-dir %S/Inputs/basic_fuchsia_tree/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ // RUN: -fuse-ld=lld 2>&1\ // RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB-X86 -// RUN: %clang %s -### --target=x86_64-fuchsia -fsanitize=address \ +// RUN: %clangxx %s -### --target=x86_64-fuchsia -fsanitize=address \ +// RUN: -ccc-install-dir %S/Inputs/basic_fuchsia_tree/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ // RUN: -fuse-ld=lld 2>&1\ // RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB-X86,CHECK-MULTILIB-ASAN-X86 -// RUN: %clang %s -### --target=x86_64-fuchsia -fno-exceptions \ +// RUN: %clangxx %s -### --target=x86_64-fuchsia -fno-exceptions \ +// RUN: -ccc-install-dir %S/Inputs/basic_fuchsia_tree/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ // RUN: -fuse-ld=lld 2>&1\ // RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB-X86,CHECK-MULTILIB-NOEXCEPT-X86 -// RUN: %clang %s -### --target=x86_64-fuchsia -fsanitize=address -fno-exceptions \ +// RUN: %clangxx %s -### --target=x86_64-fuchsia -fsanitize=address -fno-exceptions \ +// RUN: -ccc-install-dir %S/Inputs/basic_fuchsia_tree/bin \ // RUN: -resource-dir=%S/Inputs/resource_dir_with_per_target_subdir \ // RUN: -fuse-ld=lld 2>&1\ // RUN: | FileCheck %s -check-prefixes=CHECK-MULTILIB-X86,CHECK-MULTILIB-ASAN-X86 // CHECK-MULTILIB-X86: "-resource-dir" "[[RESOURCE_DIR:[^"]+]]" -// CHECK-MULTILIB-ASAN-X86: "-L[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib{{/|\\\\}}asan" -// CHECK-MULTILIB-NOEXCEPT-X86: "-L[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib{{/|\\\\}}noexcept" -// CHECK-MULTILIB-X86: "-L[[RESOURCE_DIR]]{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}lib" +// CHECK-MULTILIB-ASAN-X86: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}c++{{/|\\\\}}asan" +// CHECK-MULTILIB-NOEXCEPT-X86: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}c++{{/|\\\\}}noexcept" +// CHECK-MULTILIB-X86: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-fuchsia{{/|\\\\}}c++" Index: test/Driver/linux-per-target-runtime-dir.c =================================================================== --- test/Driver/linux-per-target-runtime-dir.c +++ test/Driver/linux-per-target-runtime-dir.c @@ -13,7 +13,6 @@ // CHECK-PER-TARGET-RUNTIME: "-internal-isystem" "[[SYSROOT]]/usr/local/include" // CHECK-PER-TARGET-RUNTIME: "--sysroot=[[SYSROOT]]" // CHECK-PER-TARGET-RUNTIME: "-L{{.*}}{{/|\\\\}}..{{/|\\\\}}lib{{/|\\\\}}x86_64-linux-gnu{{/|\\\\}}c++" -// CHECK-PER-TARGET-RUNTIME: "-L[[RESDIR]]{{/|\\\\}}x86_64-linux-gnu{{/|\\\\}}lib" // RUN: %clang -rtlib=compiler-rt -print-libgcc-file-name 2>&1 \ // RUN: --target=x86_64-linux-gnu \