mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 09:06:21 +01:00
[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:
@@ -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;
|
||||
|
||||
@@ -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)) {}
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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");
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user