[clang][Driver] Default to /usr/bin/ld on Solaris

`clang` currently requires the native linker on Solaris:

  - It passes `-C` to `ld` which GNU `ld` doesn't understand.

  - To use `gld`, one needs to pass the correct `-m EMU` option to select
    the right emulation.  Solaris `ld` cannot handle that option.

So far I've worked around this by passing `-DCLANG_DEFAULT_LINKER=/usr/bin/ld`
to `cmake`.  However, if someone forgets this, it depends on the user's
`PATH` whether or not `clang` finds the correct linker, which doesn't make
for a good user experience.

While it would be nice to detect the linker flavor at runtime, this is more
involved.  Instead, this patch defaults to `/usr/bin/ld` on Solaris.  This
doesn't work on its own, however: a link fails with

  clang-12: error: unable to execute command: Executable "x86_64-pc-solaris2.11-/usr/bin/ld" doesn't exist!

I avoid this by leaving absolute paths alone in `ToolChain::GetLinkerPath`.

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

Differential Revision: https://reviews.llvm.org/D84029
This commit is contained in:
Rainer Orth 2020-08-13 22:42:58 +02:00
parent 18910c4cb5
commit f59bec7acb
4 changed files with 21 additions and 2 deletions

View File

@ -568,8 +568,13 @@ std::string ToolChain::GetLinkerPath() const {
}
// If we're passed -fuse-ld= with no argument, or with the argument ld,
// then use whatever the default system linker is.
if (UseLinker.empty() || UseLinker == "ld")
return GetProgramPath(getDefaultLinker());
if (UseLinker.empty() || UseLinker == "ld") {
const char *DefaultLinker = getDefaultLinker();
if (llvm::sys::path::is_absolute(DefaultLinker))
return std::string(DefaultLinker);
else
return GetProgramPath(DefaultLinker);
}
// Extending -fuse-ld= to an absolute or relative path is unexpected. Checking
// for the linker flavor is brittle. In addition, prepending "ld." or "ld64."

View File

@ -65,6 +65,11 @@ public:
SanitizerMask getSupportedSanitizers() const override;
unsigned GetDefaultDwarfVersion() const override { return 2; }
const char *getDefaultLinker() const override {
// clang currently uses Solaris ld-only options.
return "/usr/bin/ld";
}
protected:
Tool *buildAssembler() const override;
Tool *buildLinker() const override;

View File

@ -0,0 +1,7 @@
// REQUIRES: system-solaris
// Check that clang invokes the native ld.
// RUN: test -f /usr/gnu/bin/ld && env PATH=/usr/gnu/bin %clang -o %t.o %s
int main() { return 0; }

View File

@ -59,6 +59,8 @@ class LLVMConfig(object):
features.add('system-netbsd')
elif platform.system() == 'AIX':
features.add('system-aix')
elif platform.system() == 'SunOS':
features.add('system-solaris')
# Native compilation: host arch == default triple arch
# Both of these values should probably be in every site config (e.g. as