Page MenuHomePhabricator

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

Authored by ro on Jul 17 2020, 8:06 AM.

Details

Summary

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.

Ok for master?

Diff Detail

Event Timeline

ro created this revision.Jul 17 2020, 8:06 AM
ro updated this revision to Diff 280108.Jul 23 2020, 7:29 AM
ro added a reviewer: MaskRay.

Rebased after D83015.

Can you add a test to test/Driver/solaris-ld.c?

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.

Not very sure about this. The last resort of GetProgramPath is PATH. On FreeBSD and Linux, this is how /usr/bin/ld gets selected. PATH can affect ld choice.

ro updated this revision to Diff 282192.Jul 31 2020, 4:57 AM

Add testcase.

Herald added a project: Restricted Project. · View Herald TranscriptJul 31 2020, 4:57 AM
ro added a comment.Jul 31 2020, 5:07 AM

Can you add a test to test/Driver/solaris-ld.c?

No, this needs a separate testcase: the -C option unconditionally passed to the linker is only understood by the native ld.

I've added solaris-ld-sld.c instead, and also need a system-solaris feature to restrict it. Since /usr/gnu/bin/ld isn't necessarily installed, there should be a way to mark the test UNSUPPORTED if it's missing. I couldn't find how to do so, though.

Tested on amd64-pc-solaris2.11 (FAILs without the patch, PASSes with it) and x86_64-pc-linux-gnu (comes up UNSUPPORTED).

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.

Not very sure about this. The last resort of GetProgramPath is PATH. On FreeBSD and Linux, this is how /usr/bin/ld gets selected. PATH can affect ld choice.

True, but all possible linkers strive to be GNU ld compatible on those systems. OTOH, on proprietary systems (Solaris, HP-UX, AIX, previsously IRIX, Tru64 UNIX) there was a native linker years if not decades before GNU ld started. Sometimes gld has added some options for compatibility with the native linker, sometimes native linkers (like the Solaris one later in the Solaris 11 cycle) added some options for gld compatiblity.

However, they usually have different options apart from the very basic ones (-L, -l, -o) and one needs to select the right one to avoid mismatches. Alternatively, one could detect the linker flavour at runtime and adapt accordingly. However, the native linkers are usually more featureful/better integrated with the system and thus the primary choice.

ro added a comment.Aug 6 2020, 2:26 PM

Ping? It's been a week...

ro added a comment.Aug 13 2020, 1:13 AM

Ping^2? It's been two weeks now and with having to specify -DCLANG_DEFAULT_LINKER=/usr/bin/ld as a workaround, many tests FAIL on Solaris.

MaskRay added inline comments.Aug 13 2020, 10:28 AM
clang/lib/Driver/ToolChain.cpp
573

swap then and else branches to avoid !

clang/test/Driver/solaris-ld-sld.c
7

!test -f /usr/gnu/bin/ld || env PATH=/usr/gnu/bin %clang %s -o /dev/null

MaskRay accepted this revision.Aug 13 2020, 10:29 AM
This revision is now accepted and ready to land.Aug 13 2020, 10:29 AM
This revision was automatically updated to reflect the committed changes.