Re: Why is main's system clang (12.0.1-rc2) using /usr/local/bin/aarch64-unknown-freebsd14.0-ld ? (such breaks things)

From: Mark Millard via toolchain <toolchain_at_freebsd.org>
Date: Mon, 19 Jul 2021 17:00:13 UTC
On 2021-Jul-19, at 07:40, David Chisnall <theraven at FreeBSD.org> wrote:

> On 19/07/2021 13:35, Mark Millard via toolchain wrote:
>> gcc is not documented to do automatically do such that I've
>> found.
> 
> GCC is not Clang.  GCC does not allow dynamically choosing the target. If you want a GCC that targets aarch64-unknown-freebsd, then you must build a copy of GCC that targets that triple.  If you want a version of clang that targets aarch64-unknown-freebsd, then you pass that to the -target argument.

[Mostly this fills in some detail rather than going in
a different direction from your notes.]

This I did not do.

> The clang driver will provide a *default* value for the -target argument if one is not provided.

And it happens to be aarch64-unknown-freebsd14.0 in my context.

>>> -flto requires LLD.  You can force that with -fuse-ld=lld.  Clang then will only find things called [{target triple}-]ld.lld
>> If I specify -flto (which I did), why is the command invalid
>> by definition (produces an error message) and so require more
>> command line options to correct the behavior to not get an
>> error? Why should the installation or removal of a incompatible
>> tool chain change the status of the system's clang++ command
>> line?
> 
> Clang does not know if ld is lld.  It expects that the linker that you provide is compatible with the linker arguments that you provide.  If lld is installed as {target}-ld, or if no {target}-ld exists and lld is installed as {somewhere on the search path}/ld, then it will work.  If the linker installed on the search path is BFD or some other mostly compatible ld, then it will work unless -flto is or some other linker flag that is not compatible with that linker is specified.  I am aware of at least three other non-lld linkers that do support LTO with LLVM,

Cool. [And a primary reason I wanted to reply.]

> clang doesn't know, for all possible linkers you might have installed, which ones support which flags.
> 
>> (The message is far from an obvious one as well, complaining
>> about a missing file path.)
> 
> Note that this error comes from your linker,

This was not obvious up front, but, yea, I figured it out before
my initial question on the lists.

> not clang.  It is a bit odd that the base system clang tries to use the gold plugin

QUOTE from https://llvm.org/docs/GoldPlugin.html
Building with link time optimization requires cooperation from the
system linker. LTO support on Linux systems is available via the
gold linker which supports LTO via plugins. This is the same
mechanism used by the GCC LTO project.

. . . The same plugin can also be used by other tools such as ar
and nm. Note that ld.bfd from binutils version 2.21.51.0.2 and
above also supports LTO via plugins. However, usage of the LLVM
gold plugin with ld.bfd is not tested and therefore not officially
supported or recommended.
END QUOTE

So if it is not using its own linker, clang presumes the plugin
is appropriate, even when it was not built/installed? Possibly
an "oddity" for a FreeBSD context but possibly a messy thing
to track.

(But the wording only allows for the "system linker" as well.)

For reference:

QUOTE
You should produce bitcode files from clang with the option
-flto. This flag will also cause clang to look for the gold
plugin in the lib directory under its prefix and pass the
-plugin option to ld. It will not look for an alternate
linker without -fuse-ld=gold, which is why you otherwise
need gold to be the installed system linker in your path.

ar and nm also accept the -plugin option and it’s possible
to to install LLVMgold.so to /usr/lib/bfd-plugins for a
seamless setup. If you built your own gold, be sure to
install the ar and nm-new you built to /usr/bin.
. . .
--- command lines ---
$ clang -flto a.c -c -o a.o      # <-- a.o is LLVM bitcode file
$ ar q a.a a.o                   # <-- a.a is an archive with LLVM bitcode
$ clang b.c -c -o b.o            # <-- b.o is native object file
$ clang -flto a.a b.o -o main    # <-- link with LLVMgold plugin
END QUOTE

> but we don't install it.  It should probably check for the existence of LLVMgold.so and not pass it to the linker if it doesn't exist.

Could well be. But does that get back into looking in a
bunch of places to be sure, and to know what would be
found based on which linker was used? May be too much
of a mess to be practical.

>> There is another message from me where I note that I'd figured
>> out the -fuse-ld=lld hack, although I omitted "ld." in the
>> example: should have been aarch64-unknown-freebsd14.0-ld.lld .
>> I'm actively using this technique because it seems to have the
>> minimal other potential consequences.
> 
> If you do anything that depends on a specific linker or linker behaviour (e.g. LTO) then specifying the linker to use is good practice, not a 'hack'.

As I understand, that other linker is supposed to be able
to support LLVM's lto via the plugin. "This is the same
mechanism used by the GCC LTO project."

But:

QUOTE
You should produce bitcode files from clang with the
option -flto. This flag will also cause clang to look
for the gold plugin in the lib directory under its
prefix and pass the -plugin option to ld. It will not
look for an alternate linker without -fuse-ld=gold,
which is why you otherwise need gold to be the
installed system linker in your path.
END QUOTE

But FreeBSD with -fuse-ld=lld works instead of the
non-existent linker that would go with -fuse-ld=gold .
This seems to be a FreeBSD mismatch with the
documentation at https://llvm.org/docs/GoldPlugin.html .

>> In the industry, it is fairly normal for a tool chain to
>> have a place unique to it that wins unless something
>> special is specified. (And that is after lots of
>> variations have been tried over the decades.) I've tried
>> to illustrate that with gcc but it is just one point and
>> I do not claim there is universal following of such.
> 
> It is also normal in the industry for a toolchain to be non-modular and to support a single target.  Both of these were considered anti-features by LLVM.

Yep.



===
Mark Millard
marklmi at yahoo.com
( dsl-only.net went
away in early 2018-Mar)