[clang] 1abd4c9 - [Clang] Bypass distro detection on non-Linux hosts

Alexandre Ganea via cfe-commits cfe-commits at lists.llvm.org
Thu Nov 28 14:03:46 PST 2019


Author: Alexandre Ganea
Date: 2019-11-28T17:02:06-05:00
New Revision: 1abd4c94d7575e4cd288e0024c1ec79f17b048a9

URL: https://github.com/llvm/llvm-project/commit/1abd4c94d7575e4cd288e0024c1ec79f17b048a9
DIFF: https://github.com/llvm/llvm-project/commit/1abd4c94d7575e4cd288e0024c1ec79f17b048a9.diff

LOG: [Clang] Bypass distro detection on non-Linux hosts

Skip distro detection when we're not running on Linux, or when the target triple is not Linux. This saves a few OS calls for each invocation of clang.exe.

Differential Revision: https://reviews.llvm.org/D70467

Added: 
    

Modified: 
    clang/include/clang/Driver/Distro.h
    clang/lib/Driver/Distro.cpp
    clang/lib/Driver/ToolChains/Clang.cpp
    clang/lib/Driver/ToolChains/Cuda.cpp
    clang/lib/Driver/ToolChains/Linux.cpp
    clang/unittests/Driver/DistroTest.cpp

Removed: 
    


################################################################################
diff  --git a/clang/include/clang/Driver/Distro.h b/clang/include/clang/Driver/Distro.h
index da8f819dee96..d382cf77a8b2 100644
--- a/clang/include/clang/Driver/Distro.h
+++ b/clang/include/clang/Driver/Distro.h
@@ -9,6 +9,7 @@
 #ifndef LLVM_CLANG_DRIVER_DISTRO_H
 #define LLVM_CLANG_DRIVER_DISTRO_H
 
+#include "llvm/ADT/Triple.h"
 #include "llvm/Support/VirtualFileSystem.h"
 
 namespace clang {
@@ -84,7 +85,7 @@ class Distro {
   Distro(DistroType D) : DistroVal(D) {}
 
   /// Detects the distribution using specified VFS.
-  explicit Distro(llvm::vfs::FileSystem &VFS);
+  explicit Distro(llvm::vfs::FileSystem &VFS, const llvm::Triple &TargetOrHost);
 
   bool operator==(const Distro &Other) const {
     return DistroVal == Other.DistroVal;

diff  --git a/clang/lib/Driver/Distro.cpp b/clang/lib/Driver/Distro.cpp
index 92e04108a7e2..06707fefc9d0 100644
--- a/clang/lib/Driver/Distro.cpp
+++ b/clang/lib/Driver/Distro.cpp
@@ -13,11 +13,28 @@
 #include "llvm/ADT/StringSwitch.h"
 #include "llvm/Support/ErrorOr.h"
 #include "llvm/Support/MemoryBuffer.h"
+#include "llvm/ADT/Triple.h"
 
 using namespace clang::driver;
 using namespace clang;
 
-static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS) {
+static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS,
+                                       const llvm::Triple &TargetOrHost) {
+  // If we don't target Linux, no need to check the distro. This saves a few
+  // OS calls.
+  if (!TargetOrHost.isOSLinux())
+    return Distro::UnknownDistro;
+
+  // If the host is not running Linux, and we're backed by a real file system,
+  // no need to check the distro. This is the case where someone is
+  // cross-compiling from BSD or Windows to Linux, and it would be meaningless
+  // to try to figure out the "distro" of the non-Linux host.
+  IntrusiveRefCntPtr<llvm::vfs::FileSystem> RealFS =
+      llvm::vfs::getRealFileSystem();
+  llvm::Triple HostTriple(llvm::sys::getProcessTriple());
+  if (!HostTriple.isOSLinux() && &VFS == RealFS.get())
+    return Distro::UnknownDistro;
+
   llvm::ErrorOr<std::unique_ptr<llvm::MemoryBuffer>> File =
       VFS.getBufferForFile("/etc/lsb-release");
   if (File) {
@@ -149,4 +166,5 @@ static Distro::DistroType DetectDistro(llvm::vfs::FileSystem &VFS) {
   return Distro::UnknownDistro;
 }
 
-Distro::Distro(llvm::vfs::FileSystem &VFS) : DistroVal(DetectDistro(VFS)) {}
+Distro::Distro(llvm::vfs::FileSystem &VFS, const llvm::Triple &TargetOrHost)
+    : DistroVal(DetectDistro(VFS, TargetOrHost)) {}

diff  --git a/clang/lib/Driver/ToolChains/Clang.cpp b/clang/lib/Driver/ToolChains/Clang.cpp
index 26d13c714670..03a6de812047 100644
--- a/clang/lib/Driver/ToolChains/Clang.cpp
+++ b/clang/lib/Driver/ToolChains/Clang.cpp
@@ -5619,7 +5619,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
                     TC.getTriple().isOSBinFormatCOFF()) &&
                       !TC.getTriple().isPS4() &&
                       !TC.getTriple().isOSNetBSD() &&
-                      !Distro(D.getVFS()).IsGentoo() &&
+                      !Distro(D.getVFS(), TC.getTriple()).IsGentoo() &&
                       !TC.getTriple().isAndroid() &&
                        TC.useIntegratedAs()))
     CmdArgs.push_back("-faddrsig");

diff  --git a/clang/lib/Driver/ToolChains/Cuda.cpp b/clang/lib/Driver/ToolChains/Cuda.cpp
index 8c704a3078ad..02871d2ce411 100644
--- a/clang/lib/Driver/ToolChains/Cuda.cpp
+++ b/clang/lib/Driver/ToolChains/Cuda.cpp
@@ -115,7 +115,8 @@ CudaInstallationDetector::CudaInstallationDetector(
     for (const char *Ver : Versions)
       Candidates.emplace_back(D.SysRoot + "/usr/local/cuda-" + Ver);
 
-    if (Distro(D.getVFS()).IsDebian() || Distro(D.getVFS()).IsUbuntu())
+    Distro Dist(D.getVFS(), llvm::Triple(llvm::sys::getProcessTriple()));
+    if (Dist.IsDebian() || Dist.IsUbuntu())
       // Special case for Debian to have nvidia-cuda-toolkit work
       // out of the box. More info on http://bugs.debian.org/882505
       Candidates.emplace_back(D.SysRoot + "/usr/lib/cuda");

diff  --git a/clang/lib/Driver/ToolChains/Linux.cpp b/clang/lib/Driver/ToolChains/Linux.cpp
index 087783875ffe..736a2d435ca5 100644
--- a/clang/lib/Driver/ToolChains/Linux.cpp
+++ b/clang/lib/Driver/ToolChains/Linux.cpp
@@ -240,7 +240,7 @@ Linux::Linux(const Driver &D, const llvm::Triple &Triple, const ArgList &Args)
                          .str());
   }
 
-  Distro Distro(D.getVFS());
+  Distro Distro(D.getVFS(), Triple);
 
   if (Distro.IsAlpineLinux() || Triple.isAndroid()) {
     ExtraOpts.push_back("-z");
@@ -511,7 +511,7 @@ std::string Linux::getDynamicLinker(const ArgList &Args) const {
   const llvm::Triple::ArchType Arch = getArch();
   const llvm::Triple &Triple = getTriple();
 
-  const Distro Distro(getDriver().getVFS());
+  const Distro Distro(getDriver().getVFS(), Triple);
 
   if (Triple.isAndroid())
     return Triple.isArch64Bit() ? "/system/bin/linker64" : "/system/bin/linker";

diff  --git a/clang/unittests/Driver/DistroTest.cpp b/clang/unittests/Driver/DistroTest.cpp
index d0c86d1c54c9..391c0baaadf5 100644
--- a/clang/unittests/Driver/DistroTest.cpp
+++ b/clang/unittests/Driver/DistroTest.cpp
@@ -44,7 +44,7 @@ TEST(DistroTest, DetectUbuntu) {
                                        "SUPPORT_URL=\"http://help.ubuntu.com/\"\n"
                                        "BUG_REPORT_URL=\"http://bugs.launchpad.net/ubuntu/\"\n"));
 
-  Distro UbuntuTrusty{UbuntuTrustyFileSystem};
+  Distro UbuntuTrusty{UbuntuTrustyFileSystem, llvm::Triple("unknown-pc-linux")};
   ASSERT_EQ(Distro(Distro::UbuntuTrusty), UbuntuTrusty);
   ASSERT_TRUE(UbuntuTrusty.IsUbuntu());
   ASSERT_FALSE(UbuntuTrusty.IsRedhat());
@@ -52,6 +52,9 @@ TEST(DistroTest, DetectUbuntu) {
   ASSERT_FALSE(UbuntuTrusty.IsDebian());
   ASSERT_FALSE(UbuntuTrusty.IsGentoo());
 
+  Distro UbuntuTrusty2{UbuntuTrustyFileSystem, llvm::Triple("unknown-pc-windows")};
+  ASSERT_EQ(Distro(Distro::UnknownDistro), UbuntuTrusty2);
+
   llvm::vfs::InMemoryFileSystem UbuntuYakketyFileSystem;
   UbuntuYakketyFileSystem.addFile("/etc/debian_version", 0,
       llvm::MemoryBuffer::getMemBuffer("stretch/sid\n"));
@@ -74,7 +77,7 @@ TEST(DistroTest, DetectUbuntu) {
                                        "VERSION_CODENAME=yakkety\n"
                                        "UBUNTU_CODENAME=yakkety\n"));
 
-  Distro UbuntuYakkety{UbuntuYakketyFileSystem};
+  Distro UbuntuYakkety{UbuntuYakketyFileSystem, llvm::Triple("unknown-pc-linux")};
   ASSERT_EQ(Distro(Distro::UbuntuYakkety), UbuntuYakkety);
   ASSERT_TRUE(UbuntuYakkety.IsUbuntu());
   ASSERT_FALSE(UbuntuYakkety.IsRedhat());
@@ -109,7 +112,7 @@ TEST(DistroTest, DetectRedhat) {
                                        "REDHAT_SUPPORT_PRODUCT=\"Fedora\"\n"
                                        "REDHAT_SUPPORT_PRODUCT_VERSION=25\n"
                                        "PRIVACY_POLICY_URL=https://fedoraproject.org/wiki/Legal:PrivacyPolicy\n"));
-  Distro Fedora25{Fedora25FileSystem};
+  Distro Fedora25{Fedora25FileSystem, llvm::Triple("unknown-pc-linux")};
   ASSERT_EQ(Distro(Distro::Fedora), Fedora25);
   ASSERT_FALSE(Fedora25.IsUbuntu());
   ASSERT_TRUE(Fedora25.IsRedhat());
@@ -146,7 +149,7 @@ TEST(DistroTest, DetectRedhat) {
                                        "REDHAT_SUPPORT_PRODUCT=\"centos\"\n"
                                        "REDHAT_SUPPORT_PRODUCT_VERSION=\"7\"\n"));
 
-  Distro CentOS7{CentOS7FileSystem};
+  Distro CentOS7{CentOS7FileSystem, llvm::Triple("unknown-pc-linux")};
   ASSERT_EQ(Distro(Distro::RHEL7), CentOS7);
   ASSERT_FALSE(CentOS7.IsUbuntu());
   ASSERT_TRUE(CentOS7.IsRedhat());
@@ -174,7 +177,7 @@ TEST(DistroTest, DetectOpenSUSE) {
                                        "HOME_URL=\"https://opensuse.org/\"\n"
                                        "ID_LIKE=\"suse\"\n"));
 
-  Distro OpenSUSELeap421{OpenSUSELeap421FileSystem};
+  Distro OpenSUSELeap421{OpenSUSELeap421FileSystem, llvm::Triple("unknown-pc-linux")};
   ASSERT_EQ(Distro(Distro::OpenSUSE), OpenSUSELeap421);
   ASSERT_FALSE(OpenSUSELeap421.IsUbuntu());
   ASSERT_FALSE(OpenSUSELeap421.IsRedhat());
@@ -200,7 +203,7 @@ TEST(DistroTest, DetectOpenSUSE) {
                                        "HOME_URL=\"https://opensuse.org/\"\n"
                                        "ID_LIKE=\"suse\"\n"));
 
-  Distro OpenSUSE132{OpenSUSE132FileSystem};
+  Distro OpenSUSE132{OpenSUSE132FileSystem, llvm::Triple("unknown-pc-linux")};
   ASSERT_EQ(Distro(Distro::OpenSUSE), OpenSUSE132);
   ASSERT_FALSE(OpenSUSE132.IsUbuntu());
   ASSERT_FALSE(OpenSUSE132.IsRedhat());
@@ -217,7 +220,7 @@ TEST(DistroTest, DetectOpenSUSE) {
       llvm::MemoryBuffer::getMemBuffer("LSB_VERSION=\"core-2.0-noarch:core-3.0-noarch:core-2.0-x86_64:core-3.0-x86_64\"\n"));
 
   // SLES10 is unsupported and therefore evaluates to unknown
-  Distro SLES10{SLES10FileSystem};
+  Distro SLES10{SLES10FileSystem, llvm::Triple("unknown-pc-linux")};
   ASSERT_EQ(Distro(Distro::UnknownDistro), SLES10);
   ASSERT_FALSE(SLES10.IsUbuntu());
   ASSERT_FALSE(SLES10.IsRedhat());
@@ -240,7 +243,7 @@ TEST(DistroTest, DetectDebian) {
                                        "SUPPORT_URL=\"http://www.debian.org/support\"\n"
                                        "BUG_REPORT_URL=\"https://bugs.debian.org/\"\n"));
 
-  Distro DebianJessie{DebianJessieFileSystem};
+  Distro DebianJessie{DebianJessieFileSystem, llvm::Triple("unknown-pc-linux")};
   ASSERT_EQ(Distro(Distro::DebianJessie), DebianJessie);
   ASSERT_FALSE(DebianJessie.IsUbuntu());
   ASSERT_FALSE(DebianJessie.IsRedhat());
@@ -259,7 +262,7 @@ TEST(DistroTest, DetectDebian) {
                                        "SUPPORT_URL=\"http://www.debian.org/support\"\n"
                                        "BUG_REPORT_URL=\"https://bugs.debian.org/\"\n"));
 
-  Distro DebianStretchSid{DebianStretchSidFileSystem};
+  Distro DebianStretchSid{DebianStretchSidFileSystem, llvm::Triple("unknown-pc-linux")};
   ASSERT_EQ(Distro(Distro::DebianStretch), DebianStretchSid);
   ASSERT_FALSE(DebianStretchSid.IsUbuntu());
   ASSERT_FALSE(DebianStretchSid.IsRedhat());
@@ -281,7 +284,7 @@ TEST(DistroTest, DetectExherbo) {
                                        "SUPPORT_URL=\"irc://irc.freenode.net/#exherbo\"\n"
                                        "BUG_REPORT_URL=\"https://bugs.exherbo.org/\"\n"));
 
-  Distro Exherbo{ExherboFileSystem};
+  Distro Exherbo{ExherboFileSystem, llvm::Triple("unknown-pc-linux")};
   ASSERT_EQ(Distro(Distro::Exherbo), Exherbo);
   ASSERT_FALSE(Exherbo.IsUbuntu());
   ASSERT_FALSE(Exherbo.IsRedhat());
@@ -303,7 +306,7 @@ TEST(DistroTest, DetectArchLinux) {
                                        "SUPPORT_URL=\"https://bbs.archlinux.org/\"\n"
                                        "BUG_REPORT_URL=\"https://bugs.archlinux.org/\"\n"));
 
-  Distro ArchLinux{ArchLinuxFileSystem};
+  Distro ArchLinux{ArchLinuxFileSystem, llvm::Triple("unknown-pc-linux")};
   ASSERT_EQ(Distro(Distro::ArchLinux), ArchLinux);
   ASSERT_FALSE(ArchLinux.IsUbuntu());
   ASSERT_FALSE(ArchLinux.IsRedhat());
@@ -328,7 +331,7 @@ TEST(DistroTest, DetectGentoo) {
           "SUPPORT_URL=\"https://www.gentoo.org/support/\"\n"
           "BUG_REPORT_URL=\"https://bugs.gentoo.org/\"\n"));
 
-  Distro Gentoo{GentooFileSystem};
+  Distro Gentoo{GentooFileSystem, llvm::Triple("unknown-pc-linux")};
   ASSERT_EQ(Distro(Distro::Gentoo), Gentoo);
   ASSERT_FALSE(Gentoo.IsUbuntu());
   ASSERT_FALSE(Gentoo.IsRedhat());
@@ -337,4 +340,57 @@ TEST(DistroTest, DetectGentoo) {
   ASSERT_TRUE(Gentoo.IsGentoo());
 }
 
+TEST(DistroTest, DetectWindowsAndCrossCompile) {
+
+  class CountingFileSystem : public llvm::vfs::ProxyFileSystem {
+  public:
+    CountingFileSystem() : ProxyFileSystem(llvm::vfs::getRealFileSystem()) {}
+
+    llvm::ErrorOr<llvm::vfs::Status> status(const llvm::Twine &Path) override {
+      ++Count;
+      return llvm::vfs::ProxyFileSystem::status(Path);
+    }
+
+    llvm::ErrorOr<std::unique_ptr<llvm::vfs::File>>
+    openFileForRead(const llvm::Twine &Path) override {
+      ++Count;
+      return llvm::vfs::ProxyFileSystem::openFileForRead(Path);
+    }
+
+    unsigned Count{};
+  };
+
+  llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem> RFS =
+      llvm::vfs::getRealFileSystem();
+  llvm::Triple Host(llvm::sys::getProcessTriple());
+
+  CountingFileSystem CFileSystem;
+  Distro LinuxDistro{CFileSystem, llvm::Triple("unknown-pc-linux")};
+  if (Host.isOSWindows()) {
+    ASSERT_EQ(Distro(Distro::UnknownDistro), LinuxDistro);
+    ASSERT_GT(CFileSystem.Count, 0U);
+  }
+
+  Distro WinDistro{CFileSystem, llvm::Triple("unknown-pc-windows")};
+  ASSERT_EQ(Distro(Distro::UnknownDistro), WinDistro);
+  ASSERT_GT(CFileSystem.Count, 0U);
+
+  // When running on Windows along with a real file system, ensure that no
+  // distro is returned if targeting Linux
+  if (Host.isOSWindows()) {
+    Distro LinuxRealDistro{*RFS, llvm::Triple("unknown-pc-linux")};
+    ASSERT_EQ(Distro(Distro::UnknownDistro), LinuxRealDistro);
+  }
+  // When running on Linux, check if the distro is the same as the host when
+  // targeting Linux
+  if (Host.isOSLinux()) {
+    Distro HostDistro{*RFS, Host};
+    Distro LinuxRealDistro{*RFS, llvm::Triple("unknown-pc-linux")};
+    ASSERT_EQ(HostDistro, LinuxRealDistro);
+  }
+
+  Distro WinRealDistro{*RFS, llvm::Triple("unknown-pc-windows")};
+  ASSERT_EQ(Distro(Distro::UnknownDistro), WinRealDistro);
+}
+
 } // end anonymous namespace


        


More information about the cfe-commits mailing list