Index: clang/include/clang/Driver/ToolChain.h =================================================================== --- clang/include/clang/Driver/ToolChain.h +++ clang/include/clang/Driver/ToolChain.h @@ -124,8 +124,8 @@ const RTTIMode CachedRTTIMode; - /// The list of toolchain specific path prefixes to search for libraries. - path_list LibraryPaths; + /// The list of toolchain specific path prefixes to search for runtimes. + path_list RuntimePaths; /// The list of toolchain specific path prefixes to search for files. path_list FilePaths; @@ -225,8 +225,8 @@ return EffectiveTriple; } - path_list &getLibraryPaths() { return LibraryPaths; } - const path_list &getLibraryPaths() const { return LibraryPaths; } + path_list &getRuntimePaths() { return RuntimePaths; } + const path_list &getRuntimePaths() const { return RuntimePaths; } path_list &getFilePaths() { return FilePaths; } const path_list &getFilePaths() const { return FilePaths; } @@ -389,6 +389,10 @@ getCompilerRTArgString(const llvm::opt::ArgList &Args, StringRef Component, FileType Type = ToolChain::FT_Static) const; + virtual Optional getRuntimePath() const; + + virtual Optional getCXXStdlibPath() const; + // Returns /lib//. This is used by runtimes (such // as OpenMP) to find arch-specific libraries. std::string getArchSpecificLibPath() const; Index: clang/lib/Driver/Driver.cpp =================================================================== --- clang/lib/Driver/Driver.cpp +++ clang/lib/Driver/Driver.cpp @@ -4422,10 +4422,10 @@ if (llvm::sys::fs::exists(Twine(P))) return P.str(); - if (auto P = SearchPaths(TC.getLibraryPaths())) + if (auto P = SearchPaths(TC.getFilePaths())) return *P; - if (auto P = SearchPaths(TC.getFilePaths())) + if (auto P = SearchPaths(TC.getRuntimePaths())) return *P; return Name; Index: clang/lib/Driver/ToolChain.cpp =================================================================== --- clang/lib/Driver/ToolChain.cpp +++ clang/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()) + getRuntimePaths().push_back(*RuntimePath); std::string CandidateLibPath = getArchSpecificLibPath(); if (getVFS().exists(CandidateLibPath)) @@ -400,11 +384,10 @@ break; } - for (const auto &LibPath : getLibraryPaths()) { + for (const auto &LibPath : getRuntimePaths()) { SmallString<128> P(LibPath); llvm::sys::path::append(P, Prefix + Twine("clang_rt.") + Component + Suffix); - if (getVFS().exists(P)) - return P.str(); + return P.str(); } StringRef Arch = getArchNameForCompilerRTLib(*this, Args); @@ -421,6 +404,39 @@ return Args.MakeArgString(getCompilerRT(Args, Component, Type)); } + +Optional ToolChain::getRuntimePath() const { + SmallString<128> P; + + P.assign(D.ResourceDir); + llvm::sys::path::append(P, D.getTargetTriple(), "lib"); + if (getVFS().exists(P)) + return llvm::Optional(P.str()); + + 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; + + P.assign(D.Dir); + llvm::sys::path::append(P, "..", "lib", D.getTargetTriple(), "c++"); + if (getVFS().exists(P)) + return llvm::Optional(P.str()); + + 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 +849,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: clang/lib/Driver/ToolChains/Fuchsia.cpp =================================================================== --- clang/lib/Driver/ToolChains/Fuchsia.cpp +++ clang/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: clang/test/Driver/fuchsia.c =================================================================== --- clang/test/Driver/fuchsia.c +++ clang/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: clang/test/Driver/fuchsia.cpp =================================================================== --- clang/test/Driver/fuchsia.cpp +++ clang/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: clang/test/Driver/linux-per-target-runtime-dir.c =================================================================== --- clang/test/Driver/linux-per-target-runtime-dir.c +++ clang/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 \