Move the GCC installation detection helper a member of the Linux

toolchain instead of merely using it in the constructor. This will allow
us to query it when building include paths as well as the file search
paths built in the constructor. I've lifted as little of it as I could
into the header file.

Eventually this will likely sink down into some of the Generic
toolchains and be used on more platforms, but I'm starting on Linux so
I can work out all the APIs needed there, where it is easiest to test
and we have the most pressing need.

llvm-svn: 143838
This commit is contained in:
Chandler Carruth 2011-11-05 22:07:51 +00:00
parent a95f344b3e
commit 14dd5ffcbf
2 changed files with 255 additions and 242 deletions

View File

@ -1527,19 +1527,12 @@ static bool PathExists(StringRef Path) {
return false; return false;
} }
namespace {
/// \brief This is a class to find a viable GCC installation for Clang to use.
///
/// This class tries to find a GCC installation on the system, and report
/// information about it. It starts from the host information provided to the
/// Driver, and has logic for fuzzing that where appropriate.
class GCCInstallationDetector {
/// \brief Struct to store and manipulate GCC versions. /// \brief Struct to store and manipulate GCC versions.
/// ///
/// We rely on assumptions about the form and structure of GCC version /// We rely on assumptions about the form and structure of GCC version
/// numbers: they consist of at most three '.'-separated components, and each /// numbers: they consist of at most three '.'-separated components, and each
/// component is a non-negative integer. /// component is a non-negative integer.
struct GCCVersion { struct Linux::GCCVersion {
unsigned Major, Minor, Patch; unsigned Major, Minor, Patch;
static GCCVersion Parse(StringRef VersionText) { static GCCVersion Parse(StringRef VersionText) {
@ -1572,21 +1565,11 @@ class GCCInstallationDetector {
bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); } bool operator>=(const GCCVersion &RHS) const { return !(*this < RHS); }
}; };
bool IsValid;
std::string GccTriple;
// FIXME: These might be better as path objects.
std::string GccInstallPath;
std::string GccParentLibPath;
llvm::SmallString<128> CxxIncludeRoot;
public:
/// \brief Construct a GCCInstallationDetector from the driver. /// \brief Construct a GCCInstallationDetector from the driver.
/// ///
/// This performs all of the autodetection and sets up the various paths. /// This performs all of the autodetection and sets up the various paths.
/// Once constructed, a GCCInstallation is esentially immutable. /// Once constructed, a GCCInstallation is esentially immutable.
GCCInstallationDetector(const Driver &D) Linux::GCCInstallationDetector::GCCInstallationDetector(const Driver &D)
: IsValid(false), : IsValid(false),
GccTriple(D.DefaultHostTriple), GccTriple(D.DefaultHostTriple),
CxxIncludeRoot(CXX_INCLUDE_ROOT) { CxxIncludeRoot(CXX_INCLUDE_ROOT) {
@ -1651,21 +1634,8 @@ public:
} }
} }
/// \brief Check whether we detected a valid GCC install. /*static*/ void Linux::GCCInstallationDetector::CollectLibDirsAndTriples(
bool isValid() const { return IsValid; } llvm::Triple::ArchType HostArch, SmallVectorImpl<StringRef> &LibDirs,
/// \brief Get the GCC triple for the detected install.
const std::string &getTriple() const { return GccTriple; }
/// \brief Get the detected GCC installation path.
const std::string &getInstallPath() const { return GccInstallPath; }
/// \brief Get the detected GCC parent lib path.
const std::string &getParentLibPath() const { return GccParentLibPath; }
private:
static void CollectLibDirsAndTriples(llvm::Triple::ArchType HostArch,
SmallVectorImpl<StringRef> &LibDirs,
SmallVectorImpl<StringRef> &Triples) { SmallVectorImpl<StringRef> &Triples) {
if (HostArch == llvm::Triple::arm || HostArch == llvm::Triple::thumb) { if (HostArch == llvm::Triple::arm || HostArch == llvm::Triple::thumb) {
static const char *const ARMLibDirs[] = { "/lib" }; static const char *const ARMLibDirs[] = { "/lib" };
@ -1723,8 +1693,8 @@ private:
} }
} }
void ScanLibDirForGCCTriple(const std::string &LibDir, void Linux::GCCInstallationDetector::ScanLibDirForGCCTriple(
StringRef CandidateTriple, const std::string &LibDir, StringRef CandidateTriple,
GCCVersion &BestVersion) { GCCVersion &BestVersion) {
// There are various different suffixes involving the triple we // There are various different suffixes involving the triple we
// check for. We also record what is necessary to walk from each back // check for. We also record what is necessary to walk from each back
@ -1773,8 +1743,6 @@ private:
} }
} }
} }
};
}
static void addPathIfExists(const std::string &Path, static void addPathIfExists(const std::string &Path,
ToolChain::path_list &Paths) { ToolChain::path_list &Paths) {
@ -1811,11 +1779,10 @@ static std::string getMultiarchTriple(const llvm::Triple TargetTriple,
} }
Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple) Linux::Linux(const HostInfo &Host, const llvm::Triple &Triple)
: Generic_ELF(Host, Triple) { : Generic_ELF(Host, Triple), GCCInstallation(getDriver()) {
llvm::Triple::ArchType Arch = llvm::Triple::ArchType Arch =
llvm::Triple(getDriver().DefaultHostTriple).getArch(); llvm::Triple(getDriver().DefaultHostTriple).getArch();
const std::string &SysRoot = getDriver().SysRoot; const std::string &SysRoot = getDriver().SysRoot;
GCCInstallationDetector GCCInstallation(getDriver());
// OpenSuse stores the linker with the compiler, add that to the search // OpenSuse stores the linker with the compiler, add that to the search
// path. // path.

View File

@ -372,6 +372,52 @@ public:
}; };
class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF { class LLVM_LIBRARY_VISIBILITY Linux : public Generic_ELF {
struct GCCVersion;
/// \brief This is a class to find a viable GCC installation for Clang to
/// use.
///
/// This class tries to find a GCC installation on the system, and report
/// information about it. It starts from the host information provided to the
/// Driver, and has logic for fuzzing that where appropriate.
class GCCInstallationDetector {
bool IsValid;
std::string GccTriple;
// FIXME: These might be better as path objects.
std::string GccInstallPath;
std::string GccParentLibPath;
llvm::SmallString<128> CxxIncludeRoot;
public:
GCCInstallationDetector(const Driver &D);
/// \brief Check whether we detected a valid GCC install.
bool isValid() const { return IsValid; }
/// \brief Get the GCC triple for the detected install.
const std::string &getTriple() const { return GccTriple; }
/// \brief Get the detected GCC installation path.
const std::string &getInstallPath() const { return GccInstallPath; }
/// \brief Get the detected GCC parent lib path.
const std::string &getParentLibPath() const { return GccParentLibPath; }
private:
static void CollectLibDirsAndTriples(llvm::Triple::ArchType HostArch,
SmallVectorImpl<StringRef> &LibDirs,
SmallVectorImpl<StringRef> &Triples);
void ScanLibDirForGCCTriple(const std::string &LibDir,
StringRef CandidateTriple,
GCCVersion &BestVersion);
};
GCCInstallationDetector GCCInstallation;
public: public:
Linux(const HostInfo &Host, const llvm::Triple& Triple); Linux(const HostInfo &Host, const llvm::Triple& Triple);