mstorsjo created this revision. mstorsjo added reviewers: martell, rnk, compnerd, mati865, ismail, yaron.keren.
If found, prefer this over looking for a similar gcc later in the system path. This implements what @martell suggested in https://reviews.llvm.org/D45152 in a much neater way. Tests still are TBD, but posting this early to see if there's comments. (How do I easily do a test that checks something relative to the clang binary, since I don't control the location of the tested binary when running tests?) Repository: rC Clang https://reviews.llvm.org/D45504 Files: lib/Driver/ToolChains/MinGW.cpp lib/Driver/ToolChains/MinGW.h Index: lib/Driver/ToolChains/MinGW.h =================================================================== --- lib/Driver/ToolChains/MinGW.h +++ lib/Driver/ToolChains/MinGW.h @@ -96,6 +96,7 @@ mutable std::unique_ptr<tools::gcc::Compiler> Compiler; void findGccLibDir(); llvm::ErrorOr<std::string> findGcc(); + llvm::ErrorOr<std::string> findClangRelativeSysroot(); }; } // end namespace toolchains Index: lib/Driver/ToolChains/MinGW.cpp =================================================================== --- lib/Driver/ToolChains/MinGW.cpp +++ lib/Driver/ToolChains/MinGW.cpp @@ -275,7 +275,8 @@ Archs.emplace_back(getTriple().getArchName()); Archs[0] += "-w64-mingw32"; Archs.emplace_back("mingw32"); - Arch = Archs[0].str(); + if (Arch.empty()) + Arch = Archs[0].str(); // lib: Arch Linux, Ubuntu, Windows // lib64: openSUSE Linux for (StringRef CandidateLib : {"lib", "lib64"}) { @@ -302,13 +303,34 @@ return make_error_code(std::errc::no_such_file_or_directory); } +llvm::ErrorOr<std::string> toolchains::MinGW::findClangRelativeSysroot() { + llvm::SmallVector<llvm::SmallString<32>, 2> Subdirs; + Subdirs.emplace_back(getTriple().str()); + Subdirs.emplace_back(getTriple().getArchName()); + Subdirs[1] += "-w64-mingw32-gcc"; + Twine ClangRoot = llvm::sys::path::parent_path(getDriver().getInstalledDir()) + + llvm::sys::path::get_separator(); + for (StringRef CandidateSubdir : Subdirs) { + Twine Subdir = ClangRoot + CandidateSubdir; + if (llvm::sys::fs::is_directory(Subdir)) { + Arch = CandidateSubdir; + return Subdir.str(); + } + } + return make_error_code(std::errc::no_such_file_or_directory); +} + toolchains::MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) { getProgramPaths().push_back(getDriver().getInstalledDir()); if (getDriver().SysRoot.size()) Base = getDriver().SysRoot; + // Look for <clang-bin>/../<triplet>; if found, use <clang-bin>/.. as the + // base as it could still be a base for a gcc setup with libgcc. + else if (llvm::ErrorOr<std::string> TargetSubdir = findClangRelativeSysroot()) + Base = llvm::sys::path::parent_path(TargetSubdir.get()); else if (llvm::ErrorOr<std::string> GPPName = findGcc()) Base = llvm::sys::path::parent_path( llvm::sys::path::parent_path(GPPName.get()));
Index: lib/Driver/ToolChains/MinGW.h =================================================================== --- lib/Driver/ToolChains/MinGW.h +++ lib/Driver/ToolChains/MinGW.h @@ -96,6 +96,7 @@ mutable std::unique_ptr<tools::gcc::Compiler> Compiler; void findGccLibDir(); llvm::ErrorOr<std::string> findGcc(); + llvm::ErrorOr<std::string> findClangRelativeSysroot(); }; } // end namespace toolchains Index: lib/Driver/ToolChains/MinGW.cpp =================================================================== --- lib/Driver/ToolChains/MinGW.cpp +++ lib/Driver/ToolChains/MinGW.cpp @@ -275,7 +275,8 @@ Archs.emplace_back(getTriple().getArchName()); Archs[0] += "-w64-mingw32"; Archs.emplace_back("mingw32"); - Arch = Archs[0].str(); + if (Arch.empty()) + Arch = Archs[0].str(); // lib: Arch Linux, Ubuntu, Windows // lib64: openSUSE Linux for (StringRef CandidateLib : {"lib", "lib64"}) { @@ -302,13 +303,34 @@ return make_error_code(std::errc::no_such_file_or_directory); } +llvm::ErrorOr<std::string> toolchains::MinGW::findClangRelativeSysroot() { + llvm::SmallVector<llvm::SmallString<32>, 2> Subdirs; + Subdirs.emplace_back(getTriple().str()); + Subdirs.emplace_back(getTriple().getArchName()); + Subdirs[1] += "-w64-mingw32-gcc"; + Twine ClangRoot = llvm::sys::path::parent_path(getDriver().getInstalledDir()) + + llvm::sys::path::get_separator(); + for (StringRef CandidateSubdir : Subdirs) { + Twine Subdir = ClangRoot + CandidateSubdir; + if (llvm::sys::fs::is_directory(Subdir)) { + Arch = CandidateSubdir; + return Subdir.str(); + } + } + return make_error_code(std::errc::no_such_file_or_directory); +} + toolchains::MinGW::MinGW(const Driver &D, const llvm::Triple &Triple, const ArgList &Args) : ToolChain(D, Triple, Args), CudaInstallation(D, Triple, Args) { getProgramPaths().push_back(getDriver().getInstalledDir()); if (getDriver().SysRoot.size()) Base = getDriver().SysRoot; + // Look for <clang-bin>/../<triplet>; if found, use <clang-bin>/.. as the + // base as it could still be a base for a gcc setup with libgcc. + else if (llvm::ErrorOr<std::string> TargetSubdir = findClangRelativeSysroot()) + Base = llvm::sys::path::parent_path(TargetSubdir.get()); else if (llvm::ErrorOr<std::string> GPPName = findGcc()) Base = llvm::sys::path::parent_path( llvm::sys::path::parent_path(GPPName.get()));
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits