C++ 使用';链接时如何指定备用链接器命令;抄送';
当您使用C++ 使用';链接时如何指定备用链接器命令;抄送';,c++,c,linker,C++,C,Linker,当您使用cc(1)链接程序时,它将调用默认的链接器命令。例如,您的编译器版本可能已构建为在类unix平台上默认使用/usr/bin/ld 是否有一种方法可以指定cc(1)(或c++(1))应该使用的不同链接器命令(例如,/usr/local/bin/ld而不是/usr/bin/ld)?我主要对gcc和clang感兴趣 我不是在寻找那些分别运行各种编译步骤的方法(例如,预处理、编译、组装、链接) 例如,我希望类似这样的东西能起到作用: env LD=/usr/local/bin/ld cc foo
cc(1)
链接程序时,它将调用默认的链接器命令。例如,您的编译器版本可能已构建为在类unix平台上默认使用/usr/bin/ld
是否有一种方法可以指定cc(1)
(或c++(1)
)应该使用的不同链接器命令(例如,/usr/local/bin/ld
而不是/usr/bin/ld
)?我主要对gcc和clang感兴趣
我不是在寻找那些分别运行各种编译步骤的方法(例如,预处理、编译、组装、链接)
例如,我希望类似这样的东西能起到作用:
env LD=/usr/local/bin/ld cc foo.c -o foo
但这对gcc或clang不起作用。当然,如果您有一个makefile,它首先构建了一个对象文件,然后调用${LD}进行链接(例如,env-LD=/usr/local/bin/LD-make
),那么它就可以工作了
更新(有一个可能的动机):使用不同于默认链接器的链接器轻松进行测试。例如,能够做到这一点是很好的:
cc --linker=/usr/local/bin/ld foo.c -o foo
相反,您必须生成对象文件,运行cc-v
以找出ld
的参数,手动运行想要使用这些参数的ld
:
cc -c foo.c
cc -v foo.c -o /dev/null
现在查看链接器调用,并手动复制/粘贴替换链接器和临时对象文件。类似这样的情况(示例取自fedora 23上的测试),您将/usr/libexec/gcc/x86_64-redhat-linux/5.3.1/collect2
替换为/usr/local/bin/ld
(尽管它与collect2
不完全相同):
正如你所见,这并不容易。注意:gcc信息页面中有关于collect2如何查找链接器程序的文档。但根据这些文档,它的第一个位置不是环境变量,也不是可以在命令行上指定的东西(例如--linker)。文件说,它首先查找“硬编码链接器文件名”。如果该文档是正确的,要强制它不使用该链接器(即欺骗它),您必须重命名默认链接器(例如,sudo mv/usr/bin/ld/usr/bin/ld.tmp disable
)
更新2:使用-B
似乎可以满足我的需要。请看下面我贴出答案的地方。我不能接受我自己的答案,但如果可以的话,我会接受-它似乎很好地解决了这个问题。GCC在内部使用(决定GCC
程序的行为,特别是它如何链接以及与什么链接器链接)。您可以对其进行配置或更改,以便拥有自己的等级库文件并使用它。或者使用(gcc
,它显式地将它传递给ld
)来提供链接器脚本
默认规范是通过gcc-dumpspecs
此外,通过使用一些gcc
命令,您会发现它试图访问,例如/usr/lib/gcc/x86_64-linux-gnu/specs
;所以把你自己的规范文件放在那里
这些规范文件是文本文件,因此您应该能够编写自己的规范文件
但我不确定这是个好主意
顺便说一句,
/usr/bin/cc
在Linux发行版上是一个符号链接(在Debian上:/usr/bin/cc->/etc/alternations/cc->/usr/bin/gcc
),可以指向某些gcc
,也可以指向某些clang
。好的,cc
(and)在POSIX中指定(当然,没有任何关于它与ld
)的关系的说明)使用-B
选项可以指定编译器将使用的可执行文件、库、包括文件和数据文件的备用搜索路径。这适用于某些版本的gcc[1]和clang(目前未记录在手册页中,至少包含clang 3.7和3.8):
请注意,这将导致cc在-B
指定的路径中搜索其他工具(例如,汇编程序)。因此,假设您在/usr/local/bin中安装了不同版本的binutils,如果您只想使用该链接器(而不是/usr/local/bin/as
,等等),您可以这样做:
mkdir /tmp/usemyld
ln -s /usr/local/bin/ld /tmp/usemyld
cc -B/tmp/usemyld foo.c -o foo
-B
有自己的一套规则,允许您覆盖gcc编译器尝试使用的不同文件(程序、库、包括文件、数据文件)。这至少可以追溯到gcc 2.95——阅读gcc手册/信息页面。我不知道-B
的行为与叮当声有多兼容。如前所述,它目前没有记录在clang手册页中。但它工作得很好,允许我选择一个备用链接器,如上图所示
gcc
还支持调用-wrapper
指定的脚本/程序<代码>叮当声没有(当前)。您还可以使用它并指向一个包装器脚本,该脚本改变编译器正在调用的程序。我不知道collect2
是否注意了-wrapper
选项(对于gcc
,collect2
至少是编译c/c++程序时调用链接器的部分)
[1]
collect2
的gcc
信息页面中记录的链接器搜索顺序表示,它将首先搜索“硬编码链接器文件名,如果gcc配置了'--with ld'选项”)。因此,如果您的gcc没有配置“-with ld”,那么它最终将在-B
指定的路径中搜索(如果它没有首先找到真实的ld
)。如果您的gcc配置了--with ld
,则-B
选项将无法帮助您指定所选的备用链接器。某些链接器易于使用-只需gcc-fuse ld=lld main.c
。这似乎是在gcc版本4的某个地方添加的<代码>-保险丝ld也可用于叮当声10.0.1
上列出了支持的链接器
-保险丝ld=bfd
使用bfd链接器而不是默认链接器
-保险丝ld=金
使用黄金链接器而不是默认链接器
-熔断器二极管=
cc -B/usr/local/bin foo.c -o foo
mkdir /tmp/usemyld
ln -s /usr/local/bin/ld /tmp/usemyld
cc -B/tmp/usemyld foo.c -o foo