3

我发现当 GCC(在 GCC 4.8 和 GCC 6.4 上尝试过)real-ld在其搜索路径中找到可执行文件时,它会默默地忽略-fuse-ld=...选项,并使用real-ld而不是适当的链接器。

$ 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!

通常,没有real-ld它会按预期工作:

$ 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

GCC 的文档表明gold将使用链接器。

collect2 的文档没有说明任何关于-fuse-ld功能的内容......

4

2 回答 2

2

tl;博士这是不可能的 [2]。这是一个特点。

我深入研究了 GCC 的collect2.c 源代码、它的历史和collect2 文档,并得出结论,基于这些文档,预期行为real-ld优先于所有其他二进制文件 [1]。

但是,启用时搜索真实ld的逻辑-fuse-ld=...是模糊的,并且在文档中没有反映......

基于源代码,据我了解 C 语言,-fuse-ld=...只有当 collect2 尝试搜索ld.

[1] 一个例外是当 GCC 用 编译时--with-ld=...,但仅适用于非交叉编译器。如果不能重建 GCC(或使用交叉编译器),它什么也不会。

[2] 不完全正确。刚刚想到了创建自己real-ld的 exec的想法ld.gold,并修改编译器搜索路径(使用-B,而不是使用-fuse-ld=...):

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

$ gcc -B /path/to/real-ld/ ...
于 2019-02-07T12:31:58.470 回答
0

删除 real-ld 并在它的地方有 ld。指向您要使用的链接器。这样 -fuse-ld=gold 将在有 ld.gold 时起作用,对于 ld.bfd 也是如此。

于 2020-10-01T15:18:03.123 回答