From 5adcec16cb8d9e7bebf310b6c07249dfd852346b Mon Sep 17 00:00:00 2001 From: David Chisnall Date: Tue, 27 Sep 2011 22:03:18 +0000 Subject: [PATCH] Check for GCC paths that have the target triple in them. This is required for a lot of cross-compile toolchains. Also add some slightly better support for -B. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@140645 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Driver/Driver.cpp | 31 +++++++++++++++++------- lib/Driver/ToolChains.cpp | 50 +++++++++++++++++++++++---------------- lib/Driver/Tools.cpp | 20 ++-------------- 3 files changed, 54 insertions(+), 47 deletions(-) diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 121abc8b8b..ed9e275f7b 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -1485,33 +1485,46 @@ std::string Driver::GetFilePath(const char *Name, const ToolChain &TC) const { return Name; } +static bool isPathExecutable(llvm::sys::Path &P, bool WantFile) { + bool Exists; + return (WantFile ? !llvm::sys::fs::exists(P.str(), Exists) && Exists + : P.canExecute()); +} + std::string Driver::GetProgramPath(const char *Name, const ToolChain &TC, bool WantFile) const { + std::string TargetSpecificExecutable(DefaultHostTriple + "-" + Name); // Respect a limited subset of the '-Bprefix' functionality in GCC by // attempting to use this prefix when lokup up program paths. for (Driver::prefix_list::const_iterator it = PrefixDirs.begin(), ie = PrefixDirs.end(); it != ie; ++it) { llvm::sys::Path P(*it); + P.appendComponent(TargetSpecificExecutable); + if (isPathExecutable(P, WantFile)) return P.str(); + P.eraseComponent(); P.appendComponent(Name); - bool Exists; - if (WantFile ? !llvm::sys::fs::exists(P.str(), Exists) && Exists - : P.canExecute()) - return P.str(); + if (isPathExecutable(P, WantFile)) return P.str(); } const ToolChain::path_list &List = TC.getProgramPaths(); for (ToolChain::path_list::const_iterator it = List.begin(), ie = List.end(); it != ie; ++it) { llvm::sys::Path P(*it); + P.appendComponent(TargetSpecificExecutable); + if (isPathExecutable(P, WantFile)) return P.str(); + P.eraseComponent(); P.appendComponent(Name); - bool Exists; - if (WantFile ? !llvm::sys::fs::exists(P.str(), Exists) && Exists - : P.canExecute()) - return P.str(); + if (isPathExecutable(P, WantFile)) return P.str(); } // If all else failed, search the path. - llvm::sys::Path P(llvm::sys::Program::FindProgramByName(Name)); + llvm::sys::Path + P(llvm::sys::Program::FindProgramByName(TargetSpecificExecutable)); + if (!P.empty()) + return P.str(); + + P = llvm::sys::Path(llvm::sys::Program::FindProgramByName( + TargetSpecificExecutable)); if (!P.empty()) return P.str(); diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 8cfe859311..8b1c59abb0 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -1477,7 +1477,8 @@ static LinuxDistro DetectLinuxDistro(llvm::Triple::ArchType Arch) { return UnknownDistro; } -static std::string findGCCBaseLibDir(const std::string &GccTriple) { +static std::string findGCCBaseLibDir(const Driver &D, + const std::string &GccTriple) { // FIXME: Using CXX_INCLUDE_ROOT is here is a bit of a hack, but // avoids adding yet another option to configure/cmake. // It would probably be cleaner to break it in two variables @@ -1510,24 +1511,33 @@ static std::string findGCCBaseLibDir(const std::string &GccTriple) { "4.2.4", "4.2.3", "4.2.2", "4.2.1", "4.2", "4.1.1"}; bool Exists; - for (unsigned i = 0; i < sizeof(GccVersions)/sizeof(char*); ++i) { - std::string Suffix = GccTriple + "/" + GccVersions[i]; - std::string t1 = "/usr/lib/gcc/" + Suffix; - if (!llvm::sys::fs::exists(t1 + "/crtbegin.o", Exists) && Exists) - return t1; - std::string t2 = "/usr/lib64/gcc/" + Suffix; - if (!llvm::sys::fs::exists(t2 + "/crtbegin.o", Exists) && Exists) - return t2; - std::string t3 = "/usr/lib/" + GccTriple + "/gcc/" + Suffix; - if (!llvm::sys::fs::exists(t3 + "/crtbegin.o", Exists) && Exists) - return t3; - if (GccTriple == "i386-linux-gnu") { - // Ubuntu 11.04 uses an unusual path. - std::string t4 = - std::string("/usr/lib/i386-linux-gnu/gcc/i686-linux-gnu/") + - GccVersions[i]; - if (!llvm::sys::fs::exists(t4 + "/crtbegin.o", Exists) && Exists) - return t4; + llvm::SmallVector Paths(D.PrefixDirs.begin(), + D.PrefixDirs.end()); + Paths.push_back("/usr/"); + const std::string *Triples[] = {&GccTriple, &D.DefaultHostTriple}; + for (llvm::SmallVector::const_iterator it = Paths.begin(), + ie = Paths.end(); it != ie; ++it) { + for (unsigned i = 0; i < sizeof(GccVersions)/sizeof(char*); ++i) { + for (unsigned j = 0; j < sizeof(Triples)/sizeof(Triples[0]); ++j) { + std::string Suffix = *Triples[j] + "/" + GccVersions[i]; + std::string t1 = *it + "gcc/" + Suffix; + if (!llvm::sys::fs::exists(t1 + "/crtbegin.o", Exists) && Exists) + return t1; + std::string t2 = *it + "lib64/gcc/" + Suffix; + if (!llvm::sys::fs::exists(t2 + "/crtbegin.o", Exists) && Exists) + return t2; + std::string t3 = *it + "lib/" + GccTriple + "/gcc/" + Suffix; + if (!llvm::sys::fs::exists(t3 + "/crtbegin.o", Exists) && Exists) + return t3; + if (GccTriple == "i386-linux-gnu") { + // Ubuntu 11.04 uses an unusual path. + std::string t4 = + std::string(*it + "lib/i386-linux-gnu/gcc/i686-linux-gnu/") + + GccVersions[i]; + if (!llvm::sys::fs::exists(t4 + "/crtbegin.o", Exists) && Exists) + return t4; + } + } } } return ""; @@ -1628,7 +1638,7 @@ Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple) GccTriple = "powerpc64-unknown-linux-gnu"; } - std::string Base = findGCCBaseLibDir(GccTriple); + std::string Base = findGCCBaseLibDir(getDriver(), GccTriple); path_list &Paths = getFilePaths(); bool Is32Bits = (getArch() == llvm::Triple::x86 || getArch() == llvm::Triple::ppc); diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index 8fafbee30d..e9c6df10ef 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -47,18 +47,6 @@ using namespace clang::driver; using namespace clang::driver::tools; using namespace clang; -/// FindTargetProgramPath - Return path of the target specific version of -/// ProgName. If it doesn't exist, return path of ProgName itself. -static std::string FindTargetProgramPath(const ToolChain &TheToolChain, - const std::string TripleString, - const char *ProgName) { - std::string Executable(TripleString + "-" + ProgName); - std::string Path(TheToolChain.GetProgramPath(Executable.c_str())); - if (Path != Executable) - return Path; - return TheToolChain.GetProgramPath(ProgName); -} - /// CheckPreprocessingOptions - Perform some validation of preprocessing /// arguments that is shared with gcc. static void CheckPreprocessingOptions(const Driver &D, const ArgList &Args) { @@ -4090,9 +4078,7 @@ void netbsd::Assemble::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(II.getFilename()); } - const char *Exec = Args.MakeArgString(FindTargetProgramPath(getToolChain(), - ToolTriple.getTriple(), - "as")); + const char *Exec = Args.MakeArgString((getToolChain().GetProgramPath("as"))); C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } @@ -4208,9 +4194,7 @@ void netbsd::Link::ConstructJob(Compilation &C, const JobAction &JA, addProfileRT(getToolChain(), Args, CmdArgs, getToolChain().getTriple()); - const char *Exec = Args.MakeArgString(FindTargetProgramPath(getToolChain(), - ToolTriple.getTriple(), - "ld")); + const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("ld")); C.addCommand(new Command(JA, *this, Exec, CmdArgs)); } -- 2.40.0