Kuchara
Kuchara

Reputation: 715

How to force GCC to use ld.gold if real-ld executable exists in compiler search path?

I've found out that when GCC (tried on GCC 4.8 and GCC 6.4) finds real-ld executable in its search path, it is silently ignoring -fuse-ld=... option, and use real-ld instead of appropriate linker.

$ echo "int main(){}" > script.c
$ ln -s /usr/bin/ld real-ld
$ gcc -fuse-ld=gold -B$PWD script.c
$ readelf --string-dump=.note.gnu.gold-version a.out
readelf: a.out: Warning: Section '.note.gnu.gold-version' was not dumped because it does not exist!

Normally, without real-ld it will work as expected:

$ echo "int main(){}" > script.c
$ gcc -fuse-ld=gold script.c
$ readelf --string-dump=.note.gnu.gold-version a.out

String dump of section '.note.gnu.gold-version':
  [     c]  GNU
  [    10]  gold 1.12

Documentation of GCC suggests that gold linker will be used.

Documentation of collect2 does not say anything about -fuse-ld feature...

Upvotes: 3

Views: 2036

Answers (2)

Paulo Neves
Paulo Neves

Reputation: 1196

Remove real-ld and in it's place have ld. pointing to the linker you want to use. This way -fuse-ld=gold will work if there is a ld.gold, same for ld.bfd.

Upvotes: 0

Kuchara
Kuchara

Reputation: 715

tl;dr It is not possible [2]. This is a feature.

I've dug deep into GCC's collect2.c source code, it's history, and collect2 documentation, and came into conclusion that, based on those documents, it is expected behavior that real-ld takes precedence over all other binaries [1].

However, logic of searching real ld, when -fuse-ld=... is enabled, is vague and does not have reflection in documentation...

Based on source code, as far as I understand C language, -fuse-ld=... feature is effective only when collect2 tries to search for ld.

[1] One exception is when GCC is compiled with --with-ld=..., but only for non-crosscompilers. It gives nothing if one cannot rebuild GCC (or uses crosscompiler).

[2] Not entirely true. Just came into hackish idea to create own real-ld that would exec ld.gold, and modify compiler search path (using -B, instead of using -fuse-ld=...):

$ cat /path/to/real-ld/real-ld
#!/bin/sh
exec ld.gold "$@"

$ gcc -B /path/to/real-ld/ ...

Upvotes: 2

Related Questions