[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