[clang] 9f97720 - [clang][driver] Dynamically select gcc-toolset/devtoolset
Timm Bäder via cfe-commits
cfe-commits at lists.llvm.org
Thu Jun 2 23:18:49 PDT 2022
Author: Timm Bäder
Date: 2022-06-03T08:12:27+02:00
New Revision: 9f97720268911abae2ad9d90e270358db234a1c1
URL: https://github.com/llvm/llvm-project/commit/9f97720268911abae2ad9d90e270358db234a1c1
DIFF: https://github.com/llvm/llvm-project/commit/9f97720268911abae2ad9d90e270358db234a1c1.diff
LOG: [clang][driver] Dynamically select gcc-toolset/devtoolset
Instead of adding all devtoolset and gcc-toolset prefixes to the list of
prefixes, just scan the /opt/rh/ directory for the one with the highest
version number and only add that one.
Differential Revision: https://reviews.llvm.org/D125862
Added:
Modified:
clang/lib/Driver/ToolChains/Gnu.cpp
clang/unittests/Driver/ToolChainTest.cpp
Removed:
################################################################################
diff --git a/clang/lib/Driver/ToolChains/Gnu.cpp b/clang/lib/Driver/ToolChains/Gnu.cpp
index b3d414f2dc78f..c6ea1d026647b 100644
--- a/clang/lib/Driver/ToolChains/Gnu.cpp
+++ b/clang/lib/Driver/ToolChains/Gnu.cpp
@@ -2130,17 +2130,31 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
// and gcc-toolsets.
if (SysRoot.empty() && TargetTriple.getOS() == llvm::Triple::Linux &&
D.getVFS().exists("/opt/rh")) {
- Prefixes.push_back("/opt/rh/gcc-toolset-11/root/usr");
- Prefixes.push_back("/opt/rh/gcc-toolset-10/root/usr");
- Prefixes.push_back("/opt/rh/devtoolset-11/root/usr");
- Prefixes.push_back("/opt/rh/devtoolset-10/root/usr");
- Prefixes.push_back("/opt/rh/devtoolset-9/root/usr");
- Prefixes.push_back("/opt/rh/devtoolset-8/root/usr");
- Prefixes.push_back("/opt/rh/devtoolset-7/root/usr");
- Prefixes.push_back("/opt/rh/devtoolset-6/root/usr");
- Prefixes.push_back("/opt/rh/devtoolset-4/root/usr");
- Prefixes.push_back("/opt/rh/devtoolset-3/root/usr");
- Prefixes.push_back("/opt/rh/devtoolset-2/root/usr");
+ // Find the directory in /opt/rh/ starting with gcc-toolset-* or
+ // devtoolset-* with the highest version number and add that
+ // one to our prefixes.
+ std::string ChosenToolsetDir;
+ unsigned ChosenToolsetVersion = 0;
+ std::error_code EC;
+ for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin("/opt/rh", EC),
+ LE;
+ !EC && LI != LE; LI = LI.increment(EC)) {
+ StringRef ToolsetDir = llvm::sys::path::filename(LI->path());
+ unsigned ToolsetVersion;
+ if ((!ToolsetDir.startswith("gcc-toolset-") &&
+ !ToolsetDir.startswith("devtoolset-")) ||
+ ToolsetDir.substr(ToolsetDir.rfind('-') + 1)
+ .getAsInteger(10, ToolsetVersion))
+ continue;
+
+ if (ToolsetVersion > ChosenToolsetVersion) {
+ ChosenToolsetVersion = ToolsetVersion;
+ ChosenToolsetDir = "/opt/rh/" + ToolsetDir.str();
+ }
+ }
+
+ if (ChosenToolsetVersion > 0)
+ Prefixes.push_back(ChosenToolsetDir);
}
// Fall back to /usr which is used by most non-Solaris systems.
diff --git a/clang/unittests/Driver/ToolChainTest.cpp b/clang/unittests/Driver/ToolChainTest.cpp
index f412c35695549..3f59fd4b94616 100644
--- a/clang/unittests/Driver/ToolChainTest.cpp
+++ b/clang/unittests/Driver/ToolChainTest.cpp
@@ -18,6 +18,7 @@
#include "clang/Driver/Driver.h"
#include "llvm/ADT/ArrayRef.h"
#include "llvm/MC/TargetRegistry.h"
+#include "llvm/Support/Host.h"
#include "llvm/Support/TargetSelect.h"
#include "llvm/Support/VirtualFileSystem.h"
#include "llvm/Support/raw_ostream.h"
@@ -561,4 +562,94 @@ TEST(DxcModeTest, ValidatorVersionValidation) {
DiagConsumer->clear();
}
+TEST(ToolChainTest, Toolsets) {
+ // Ignore this test on Windows hosts.
+ llvm::Triple Host(llvm::sys::getProcessTriple());
+ if (Host.isOSWindows())
+ GTEST_SKIP();
+
+ IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
+ IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
+
+ // Check (newer) GCC toolset installation.
+ {
+ IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
+ new llvm::vfs::InMemoryFileSystem);
+
+ // These should be ignored.
+ InMemoryFileSystem->addFile("/opt/rh/gcc-toolset-2", 0,
+ llvm::MemoryBuffer::getMemBuffer("\n"));
+ InMemoryFileSystem->addFile("/opt/rh/gcc-toolset-", 0,
+ llvm::MemoryBuffer::getMemBuffer("\n"));
+ InMemoryFileSystem->addFile("/opt/rh/gcc-toolset--", 0,
+ llvm::MemoryBuffer::getMemBuffer("\n"));
+ InMemoryFileSystem->addFile("/opt/rh/gcc-toolset--1", 0,
+ llvm::MemoryBuffer::getMemBuffer("\n"));
+
+ // File needed for GCC installation detection.
+ InMemoryFileSystem->addFile(
+ "/opt/rh/gcc-toolset-12/lib/gcc/x86_64-redhat-linux/11/crtbegin.o", 0,
+ llvm::MemoryBuffer::getMemBuffer("\n"));
+
+ DiagnosticsEngine Diags(DiagID, &*DiagOpts, new SimpleDiagnosticConsumer);
+ Driver TheDriver("/bin/clang", "x86_64-redhat-linux", Diags,
+ "clang LLVM compiler", InMemoryFileSystem);
+ std::unique_ptr<Compilation> C(
+ TheDriver.BuildCompilation({"--gcc-toolchain="}));
+ ASSERT_TRUE(C);
+ std::string S;
+ {
+ llvm::raw_string_ostream OS(S);
+ C->getDefaultToolChain().printVerboseInfo(OS);
+ }
+ EXPECT_EQ("Found candidate GCC installation: "
+ "/opt/rh/gcc-toolset-12/lib/gcc/x86_64-redhat-linux/11\n"
+ "Selected GCC installation: "
+ "/opt/rh/gcc-toolset-12/lib/gcc/x86_64-redhat-linux/11\n"
+ "Candidate multilib: .;@m64\n"
+ "Selected multilib: .;@m64\n",
+ S);
+ }
+
+ // And older devtoolset.
+ {
+ IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
+ new llvm::vfs::InMemoryFileSystem);
+
+ // These should be ignored.
+ InMemoryFileSystem->addFile("/opt/rh/devtoolset-2", 0,
+ llvm::MemoryBuffer::getMemBuffer("\n"));
+ InMemoryFileSystem->addFile("/opt/rh/devtoolset-", 0,
+ llvm::MemoryBuffer::getMemBuffer("\n"));
+ InMemoryFileSystem->addFile("/opt/rh/devtoolset--", 0,
+ llvm::MemoryBuffer::getMemBuffer("\n"));
+ InMemoryFileSystem->addFile("/opt/rh/devtoolset--1", 0,
+ llvm::MemoryBuffer::getMemBuffer("\n"));
+
+ // File needed for GCC installation detection.
+ InMemoryFileSystem->addFile(
+ "/opt/rh/devtoolset-12/lib/gcc/x86_64-redhat-linux/11/crtbegin.o", 0,
+ llvm::MemoryBuffer::getMemBuffer("\n"));
+
+ DiagnosticsEngine Diags(DiagID, &*DiagOpts, new SimpleDiagnosticConsumer);
+ Driver TheDriver("/bin/clang", "x86_64-redhat-linux", Diags,
+ "clang LLVM compiler", InMemoryFileSystem);
+ std::unique_ptr<Compilation> C(
+ TheDriver.BuildCompilation({"--gcc-toolchain="}));
+ ASSERT_TRUE(C);
+ std::string S;
+ {
+ llvm::raw_string_ostream OS(S);
+ C->getDefaultToolChain().printVerboseInfo(OS);
+ }
+ EXPECT_EQ("Found candidate GCC installation: "
+ "/opt/rh/devtoolset-12/lib/gcc/x86_64-redhat-linux/11\n"
+ "Selected GCC installation: "
+ "/opt/rh/devtoolset-12/lib/gcc/x86_64-redhat-linux/11\n"
+ "Candidate multilib: .;@m64\n"
+ "Selected multilib: .;@m64\n",
+ S);
+ }
+}
+
} // end anonymous namespace.
More information about the cfe-commits
mailing list