Reputation: 715
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
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
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