Commit bec38f0d authored by Chandler Carruth's avatar Chandler Carruth
Browse files

Merging r143838:

------------------------------------------------------------------------
r143838 | chandlerc | 2011-11-05 15:07:51 -0700 (Sat, 05 Nov 2011) | 10 lines

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: 143940
parent 246dabac
Loading
Loading
Loading
Loading
+203 −236
Original line number Diff line number Diff line
@@ -1529,19 +1529,12 @@ static bool PathExists(StringRef Path) {
  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.
///
/// We rely on assumptions about the form and structure of GCC version
/// numbers: they consist of at most three '.'-separated components, and each
/// component is a non-negative integer.
  struct GCCVersion {
struct Linux::GCCVersion {
  unsigned Major, Minor, Patch;

  static GCCVersion Parse(StringRef VersionText) {
@@ -1574,21 +1567,11 @@ class GCCInstallationDetector {
  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.
///
/// This performs all of the autodetection and sets up the various paths.
/// Once constructed, a GCCInstallation is esentially immutable.
  GCCInstallationDetector(const Driver &D)
Linux::GCCInstallationDetector::GCCInstallationDetector(const Driver &D)
  : IsValid(false),
    GccTriple(D.DefaultHostTriple),
    CxxIncludeRoot(CXX_INCLUDE_ROOT) {
@@ -1653,21 +1636,8 @@ public:
  }
}

  /// \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,
/*static*/ void Linux::GCCInstallationDetector::CollectLibDirsAndTriples(
    llvm::Triple::ArchType HostArch, SmallVectorImpl<StringRef> &LibDirs,
    SmallVectorImpl<StringRef> &Triples) {
  if (HostArch == llvm::Triple::arm || HostArch == llvm::Triple::thumb) {
    static const char *const ARMLibDirs[] = { "/lib" };
@@ -1725,8 +1695,8 @@ private:
  }
}

  void ScanLibDirForGCCTriple(const std::string &LibDir,
                              StringRef CandidateTriple,
void Linux::GCCInstallationDetector::ScanLibDirForGCCTriple(
    const std::string &LibDir, StringRef CandidateTriple,
    GCCVersion &BestVersion) {
  // There are various different suffixes involving the triple we
  // check for. We also record what is necessary to walk from each back
@@ -1775,8 +1745,6 @@ private:
    }
  }
}
};
}

static void addPathIfExists(const std::string &Path,
                            ToolChain::path_list &Paths) {
@@ -1819,11 +1787,10 @@ static std::string getMultiarchTriple(const llvm::Triple TargetTriple,
}

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(getDriver().DefaultHostTriple).getArch();
  const std::string &SysRoot = getDriver().SysRoot;
  GCCInstallationDetector GCCInstallation(getDriver());

  // OpenSuse stores the linker with the compiler, add that to the search
  // path.
+46 −0
Original line number Diff line number Diff line
@@ -372,6 +372,52 @@ public:
};

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:
  Linux(const HostInfo &Host, const llvm::Triple& Triple);