Skip to content

Commit

Permalink
[Driver] Select newest GCC installation on Solaris
Browse files Browse the repository at this point in the history
As described in Issue #53709
<#53709>, since
28d58d8
<https://reviews.llvm.org/rG28d58d8fe2094af6902dee7b4d68ec30a3e9d737>
`clang` doesn't find the latest of several parallel GCC installations on
Solaris, but only the first in directory order, which is pretty random.

This patch sorts GCC installations in reverse version order so the latest
is picked.

Tested on `sparcv9-sun-solaris2.11`, `amd64-pc-solaris2.11`, and
`x86_64-pc-linux-gnu`.

Differential Revision: https://reviews.llvm.org/D157275
  • Loading branch information
rorth committed Aug 16, 2023
1 parent c5f763b commit ae84ad1
Show file tree
Hide file tree
Showing 2 changed files with 156 additions and 1 deletion.
8 changes: 7 additions & 1 deletion clang/lib/Driver/ToolChains/Gnu.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2227,6 +2227,7 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
// so we need to find those /usr/gcc/*/lib/gcc libdirs and go with
// /usr/gcc/<version> as a prefix.

SmallVector<std::pair<GCCVersion, std::string>, 8> SolarisPrefixes;
std::string PrefixDir = concat(SysRoot, "/usr/gcc");
std::error_code EC;
for (llvm::vfs::directory_iterator LI = D.getVFS().dir_begin(PrefixDir, EC),
Expand All @@ -2244,8 +2245,13 @@ void Generic_GCC::GCCInstallationDetector::AddDefaultGCCPrefixes(
if (!D.getVFS().exists(CandidateLibPath))
continue;

Prefixes.push_back(CandidatePrefix);
SolarisPrefixes.emplace_back(
std::make_pair(CandidateVersion, CandidatePrefix));
}
// Sort in reverse order so GCCInstallationDetector::init picks the latest.
std::sort(SolarisPrefixes.rbegin(), SolarisPrefixes.rend());
for (auto p : SolarisPrefixes)
Prefixes.emplace_back(p.second);
return;
}

Expand Down
149 changes: 149 additions & 0 deletions clang/unittests/Driver/ToolChainTest.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -168,6 +168,155 @@ TEST(ToolChainTest, VFSGCCInstallationRelativeDir) {
S);
}

TEST(ToolChainTest, VFSSolarisMultiGCCInstallation) {
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();

IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
struct TestDiagnosticConsumer : public DiagnosticConsumer {};
IntrusiveRefCntPtr<llvm::vfs::InMemoryFileSystem> InMemoryFileSystem(
new llvm::vfs::InMemoryFileSystem);

const char *EmptyFiles[] = {
// Sort entries so the latest version doesn't come first.
"/usr/gcc/7/lib/gcc/sparcv9-sun-solaris2.11/7.5.0/32/crtbegin.o",
"/usr/gcc/7/lib/gcc/sparcv9-sun-solaris2.11/7.5.0/crtbegin.o",
"/usr/gcc/7/lib/gcc/x86_64-pc-solaris2.11/7.5.0/32/crtbegin.o",
"/usr/gcc/7/lib/gcc/x86_64-pc-solaris2.11/7.5.0/crtbegin.o",
"/usr/gcc/11/lib/gcc/sparcv9-sun-solaris2.11/11.4.0/crtbegin.o",
"/usr/gcc/11/lib/gcc/sparcv9-sun-solaris2.11/11.4.0/sparcv8plus/"
"crtbegin.o",
"/usr/gcc/11/lib/gcc/x86_64-pc-solaris2.11/11.4.0/32/crtbegin.o",
"/usr/gcc/11/lib/gcc/x86_64-pc-solaris2.11/11.4.0/crtbegin.o",
"/usr/gcc/4.7/lib/gcc/i386-pc-solaris2.11/4.7.3/amd64/crtbegin.o",
"/usr/gcc/4.7/lib/gcc/i386-pc-solaris2.11/4.7.3/crtbegin.o",
"/usr/gcc/4.7/lib/gcc/sparc-sun-solaris2.11/4.7.3/crtbegin.o",
"/usr/gcc/4.7/lib/gcc/sparc-sun-solaris2.11/4.7.3/sparcv9/crtbegin.o",
};

for (const char *Path : EmptyFiles)
InMemoryFileSystem->addFile(Path, 0,
llvm::MemoryBuffer::getMemBuffer("\n"));

{
DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
Driver TheDriver("/bin/clang", "i386-pc-solaris2.11", Diags,
"clang LLVM compiler", InMemoryFileSystem);
std::unique_ptr<Compilation> C(
TheDriver.BuildCompilation({"-v", "--gcc-toolchain=", "--sysroot="}));
ASSERT_TRUE(C);
std::string S;
{
llvm::raw_string_ostream OS(S);
C->getDefaultToolChain().printVerboseInfo(OS);
}
if (is_style_windows(llvm::sys::path::Style::native))
std::replace(S.begin(), S.end(), '\\', '/');
EXPECT_EQ("Found candidate GCC installation: "
"/usr/gcc/11/lib/gcc/x86_64-pc-solaris2.11/11.4.0\n"
"Selected GCC installation: "
"/usr/gcc/11/lib/gcc/x86_64-pc-solaris2.11/11.4.0\n"
"Candidate multilib: .;@m64\n"
"Candidate multilib: 32;@m32\n"
"Selected multilib: 32;@m32\n",
S);
}

{
DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
Driver TheDriver("/bin/clang", "amd64-pc-solaris2.11", Diags,
"clang LLVM compiler", InMemoryFileSystem);
std::unique_ptr<Compilation> C(
TheDriver.BuildCompilation({"-v", "--gcc-toolchain=", "--sysroot="}));
ASSERT_TRUE(C);
std::string S;
{
llvm::raw_string_ostream OS(S);
C->getDefaultToolChain().printVerboseInfo(OS);
}
if (is_style_windows(llvm::sys::path::Style::native))
std::replace(S.begin(), S.end(), '\\', '/');
EXPECT_EQ("Found candidate GCC installation: "
"/usr/gcc/11/lib/gcc/x86_64-pc-solaris2.11/11.4.0\n"
"Selected GCC installation: "
"/usr/gcc/11/lib/gcc/x86_64-pc-solaris2.11/11.4.0\n"
"Candidate multilib: .;@m64\n"
"Candidate multilib: 32;@m32\n"
"Selected multilib: .;@m64\n",
S);
}

{
DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
Driver TheDriver("/bin/clang", "x86_64-pc-solaris2.11", Diags,
"clang LLVM compiler", InMemoryFileSystem);
std::unique_ptr<Compilation> C(
TheDriver.BuildCompilation({"-v", "--gcc-toolchain=", "--sysroot="}));
ASSERT_TRUE(C);
std::string S;
{
llvm::raw_string_ostream OS(S);
C->getDefaultToolChain().printVerboseInfo(OS);
}
if (is_style_windows(llvm::sys::path::Style::native))
std::replace(S.begin(), S.end(), '\\', '/');
EXPECT_EQ("Found candidate GCC installation: "
"/usr/gcc/11/lib/gcc/x86_64-pc-solaris2.11/11.4.0\n"
"Selected GCC installation: "
"/usr/gcc/11/lib/gcc/x86_64-pc-solaris2.11/11.4.0\n"
"Candidate multilib: .;@m64\n"
"Candidate multilib: 32;@m32\n"
"Selected multilib: .;@m64\n",
S);
}

{
DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
Driver TheDriver("/bin/clang", "sparc-sun-solaris2.11", Diags,
"clang LLVM compiler", InMemoryFileSystem);
std::unique_ptr<Compilation> C(
TheDriver.BuildCompilation({"-v", "--gcc-toolchain=", "--sysroot="}));
ASSERT_TRUE(C);
std::string S;
{
llvm::raw_string_ostream OS(S);
C->getDefaultToolChain().printVerboseInfo(OS);
}
if (is_style_windows(llvm::sys::path::Style::native))
std::replace(S.begin(), S.end(), '\\', '/');
EXPECT_EQ("Found candidate GCC installation: "
"/usr/gcc/11/lib/gcc/sparcv9-sun-solaris2.11/11.4.0\n"
"Selected GCC installation: "
"/usr/gcc/11/lib/gcc/sparcv9-sun-solaris2.11/11.4.0\n"
"Candidate multilib: .;@m64\n"
"Candidate multilib: sparcv8plus;@m32\n"
"Selected multilib: sparcv8plus;@m32\n",
S);
}
{
DiagnosticsEngine Diags(DiagID, &*DiagOpts, new TestDiagnosticConsumer);
Driver TheDriver("/bin/clang", "sparcv9-sun-solaris2.11", Diags,
"clang LLVM compiler", InMemoryFileSystem);
std::unique_ptr<Compilation> C(
TheDriver.BuildCompilation({"-v", "--gcc-toolchain=", "--sysroot="}));
ASSERT_TRUE(C);
std::string S;
{
llvm::raw_string_ostream OS(S);
C->getDefaultToolChain().printVerboseInfo(OS);
}
if (is_style_windows(llvm::sys::path::Style::native))
std::replace(S.begin(), S.end(), '\\', '/');
EXPECT_EQ("Found candidate GCC installation: "
"/usr/gcc/11/lib/gcc/sparcv9-sun-solaris2.11/11.4.0\n"
"Selected GCC installation: "
"/usr/gcc/11/lib/gcc/sparcv9-sun-solaris2.11/11.4.0\n"
"Candidate multilib: .;@m64\n"
"Candidate multilib: sparcv8plus;@m32\n"
"Selected multilib: .;@m64\n",
S);
}
}

TEST(ToolChainTest, DefaultDriverMode) {
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();

Expand Down

0 comments on commit ae84ad1

Please sign in to comment.