[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
This commit is contained in:
Alexandre Ganea
2019-11-28 17:02:06 -05:00
parent a7abe6eac0
commit 1abd4c94d7
6 changed files with 95 additions and 19 deletions
+2 -1
View File
@@ -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 @@ public:
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;
+20 -2
View File
@@ -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)) {}
+1 -1
View File
@@ -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");
+2 -1
View File
@@ -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");
+2 -2
View File
@@ -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";
+68 -12
View File
@@ -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