This is an archive of the discontinued LLVM Phabricator instance.

[Driver] Support GNU ld on Solaris
ClosedPublic

Authored by ro on Aug 5 2020, 7:20 AM.

Details

Summary

This patch is posted just for reference on top of D84029 and D84412.

It's a very first attempt to support GNU ld on Solaris, which is non-trivial given that
both linkers have some options not supported by the other. Currently linker selection
is done at cmake time; it probably needs to be made runtime-selectable.

Diff Detail

Event Timeline

ro created this revision.Aug 5 2020, 7:20 AM
ro requested review of this revision.Aug 5 2020, 7:20 AM

Please find a suitable test file (clang/test/Driver/solaris-*.c) and add some tests there (for example, solaris-ld.c)
The challenge is that CLANG_ENABLE_GLD is not a default configuration, so leaving out tests may be fine.

clang/CMakeLists.txt
281 ↗(On Diff #283230)

Mention SOLARIS in the variable name? Users on other OSes don't need to read the description of this variable.

It will also make the abbreviation GLD more legitimate. GLD isn't a well-recognized abbreviation for GNU ld.

clang/lib/Driver/ToolChains/Solaris.cpp
354

The hard-coded version doesn't sound great.

ro added a comment.Aug 6 2020, 2:13 AM

Please find a suitable test file (clang/test/Driver/solaris-*.c) and add some tests there (for example, solaris-ld.c)
The challenge is that CLANG_ENABLE_GLD is not a default configuration, so leaving out tests may be fine.

On top of that, GNU ld may or may not be installed on a particular Solaris systems. So even if the configuration were dynamic instead of hardcoding GNU ld, one would still have to make the test conditional on its presence on the actual system. Same as the somewhat hacky test in D84029.

That said, I don't consider this patch even remotely ready for inclusion. It was primarily meant to show what I'd been using to test that configuration. It has been useful in pinpointing differences between Solaris ld and GNU ld testresults. However, there are quite a number of unexpected asan failures that need to be investigated first.

I'm also not happy with selecting the linker flavour at build time: maybe this can be made dynamic (e.g. parsing ld -V output) to allow for switching between Solaris ld and GNU ld at runtime.

clang/CMakeLists.txt
281 ↗(On Diff #283230)

As I said, I've only done it this way to allow selecting GNU ld at all. This would become moot if linker flavour detection were
implemented at runtime.

clang/lib/Driver/ToolChains/Solaris.cpp
354

Certainly not: this is a site-local path used to hack around a configuration error in the current bundled GNU ld on Solaris.
That one is being fixed as we speak.

ro updated this revision to Diff 554711.Aug 30 2023, 7:40 AM
ro retitled this revision from [WIP][clang][Driver] Support GNU ld on Solaris to [Driver] Support GNU ld on Solaris.

This is a major revison of the original WIP patch that should be (close to) ready. Major differences are:

  • Linker selection is dynamic now: one can switch between Solaris ld and GNU ld at runtime, with the default selectable with -DCLANG_DEFAULT_LINKER.
  • Testcases have been adjusted to test both variants in case there are differences.
  • The compiler-rt/cmake/config-ix.cmake and llvm/cmake/modules/AddLLVM.cmake changes to restrict the tests to Solaris ld are necessary because GNU accepts unknown -z options, but warns every time they are used, creating a lot of noise. Since there seems to be no way to check for those warnings in llvm_check_compiler_linker_flag or llvm_check_compiler_linker_flag, I restrict the cmake tests to Solaris ld in the first place.
  • The changes to clang/test/Driver/hip-link-bundle-archive.hip and flang/test/Driver/linker-flags.f90 are required to handle the -DCLANG_DEFAULT_LINKER=gld case: when this is passed to cmake, the WebAssembly.cpp getLinkerPath returns /usr/bin/gld instead of the expected link.
  • compiler-rt/test/asan/TestCases/global-location-nodebug.cpp needs to enforce the Solaris ld, otherwise the test would XPASS with GNU ld which has the -S semantics expected by the test.

Tested on amd64-pc-solaris2.11 and sparcv9-sun-solaris2.11 with both -DCLANG_DEFAULT_LINKER=gld and the default, and x86_64-pc-linux-gnu. No regressions in either case.

Herald added projects: Restricted Project, Restricted Project, Restricted Project, Restricted Project. · View Herald Transcript
Herald added subscribers: llvm-commits, Restricted Project, Enna1, ormris. · View Herald Transcript
MaskRay added inline comments.Aug 30 2023, 2:10 PM
clang/lib/Driver/ToolChains/CommonArgs.cpp
306

I suppose that this should be in a Solaris specific file to indicate that it's not for other systems.

GNU ld is almost ubiquitous on Linux and is almost always available at /usr/bin/ld (with very few distributions using others linkers by default or providing an option).

Detecting linker to affect driver decisions is we Linux are very wary of. We are nervous even trying to do some stuff only related to lld.

We likely don't want this function to be in CommonArgs to lure other contributors to use.

ro marked an inline comment as done.Aug 31 2023, 2:35 AM
ro added inline comments.
clang/lib/Driver/ToolChains/CommonArgs.cpp
306

I suppose that this should be in a Solaris specific file to indicate that it's not for other systems.

Indeed. I've moved it to Solaris.{h,cpp} now. In fact, initially i'd tried to assert a Solaris target in isLinkerGnuLd, but that cannot work because in some cases the function is called in common code, even though the result is only used on Solaris.

I briefly thought about generalizing both IsLinkerGnuLd and IsLinkerLLD into a common

enum LinkerFlavour getLinkerFlavor();

but doing this for all possible configs seemed like a can of worms I'd rather not open.

GNU ld is almost ubiquitous on Linux and is almost always available at /usr/bin/ld (with very few distributions using others linkers by default or providing an option).

Detecting linker to affect driver decisions is we Linux are very wary of. We are nervous even trying to do some stuff only related to lld.

I saw: that code is only used on Darwin, it seems, and I'd like to avoid touching that.

We likely don't want this function to be in CommonArgs to lure other contributors to use.

Apart from the move to Solaris.h, I've also moved it into the solaris namespace to make things completely obvious.

ro updated this revision to Diff 554946.Aug 31 2023, 2:38 AM
ro marked an inline comment as done.

Move isLinkerGnuLd to Solaris.{h,cpp} and into solaris namespace to make it unambigously clear where to use it.

MaskRay added inline comments.Aug 31 2023, 11:19 AM
clang/test/Driver/hip-link-bundle-archive.hip
59

Any idea why -fuse-ld= is now needed?

ro added inline comments.Aug 31 2023, 11:34 AM
clang/test/Driver/hip-link-bundle-archive.hip
59

I've tried to explain it in the change description, but just noticed the filename is wrong:

When LLVM is built with -DCLANG_DEFAULT_LINKER=gld on Solaris, MSVC.cpp visualstudio::Linker::ConstructJob sets Linker to gld. Ultimately, GetProgramPath(Linker) is called, resulting in a search for gld, which exists in /usr/bin/gld on Solaris. With -fuse-ld=, this doesn't happen and the expected link is returned.

MaskRay accepted this revision.Sep 1 2023, 11:28 AM

LGTM.

clang/lib/Driver/ToolChains/Solaris.cpp
55

-fuse-ld=<path> is deprecated by --ld-path=. So just drop this FIXME.

83
This revision is now accepted and ready to land.Sep 1 2023, 11:28 AM
ro marked 2 inline comments as done.Sep 1 2023, 12:41 PM
This revision was landed with ongoing or failed builds.Sep 1 2023, 12:43 PM
This revision was automatically updated to reflect the committed changes.