Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 使用';链接时如何指定备用链接器命令;抄送';_C++_C_Linker - Fatal编程技术网

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