与"cc"链接时如何指定备用链接器命令 [英] how to specify alternate linker command when linking with 'cc'

查看:86
本文介绍了与"cc"链接时如何指定备用链接器命令的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

使用cc(1)链接程序时,它将调用默认的链接程序命令.例如,您的编译器版本可能已构建为在类似Unix的平台上默认使用/usr/bin/ld.

When you use cc(1) to link a program, it will invoke a default linker command. For instance, your version of the compiler may have been built to use /usr/bin/ld by default on a unix-like platform.

是否可以指定cc(1)(或c++(1))应使用的其他链接器命令(例如,/usr/local/bin/ld而不是/usr/bin/ld)?我主要对gcc和clang感兴趣.

Is there a way to specify a different linker command that cc(1) (or c++(1)) should use (e.g., /usr/local/bin/ld instead of /usr/bin/ld)? I'm interested mostly in gcc and clang.

我不是在寻找涉及分别运行各个编译步骤(例如,预处理,编译,汇编,链接)的方法.

I'm not looking for methods that involve running the various compilation steps separately (e.g., pre-process, compile, assemble, link).

例如,我希望这样的事情可以完成工作:

For example, I was hoping something like this might do the job:

env LD=/usr/local/bin/ld cc foo.c -o foo

但这不适用于gcc或clang.当然,如果您有一个先生成目标文件的生成文件,然后调用$ {LD}进行链接(例如,env LD=/usr/local/bin/ld make)

But that doesn't work for gcc or clang. It would work, of course, if you had a makefile that built an object file first, then invoked ${LD} to link (e.g., env LD=/usr/local/bin/ld make)

更新(有一种可能的动机):使用不同于默认链接程序的链接程序轻松进行测试.例如,很高兴能够做到这一点:

Update (with one possible motivation): To easily test with a different linker than the default linker. For example, it would be nice to be able to do this:

cc --linker=/usr/local/bin/ld foo.c -o foo

相反,您必须生成目标文件,运行cc -v找出ld的参数,并使用这些参数手动运行所需的ld:

Instead, you have to do generate the object file, run cc -v to figure out the arguments to ld, manually run the ld you want with those arguments:

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完全不一样),

Now look at the linker invocation and manually copy/paste replacing linker and temporary object file. Something like this (example taken from a test on fedora 23) where you replace /usr/libexec/gcc/x86_64-redhat-linux/5.3.1/collect2 with /usr/local/bin/ld (although it's not exactly the same as collect2):

/usr/local/bin/ld -plugin /usr/libexec/gcc/x86_64-redhat-linux/5.3.1/liblto_plugin.so -plugin-opt=/usr/libexec/gcc/x86_64-redhat-linux/5.3.1/lto-wrapper -plugin-opt=-fresolution=/tmp/jhein/ccM2XKIg.res -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s -plugin-opt=-pass-through=-lc -plugin-opt=-pass-through=-lgcc -plugin-opt=-pass-through=-lgcc_s --build-id --no-add-needed --eh-frame-hdr --hash-style=gnu -m elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2 -o c /usr/lib/gcc/x86_64-redhat-linux/5.3.1/../../../../lib64/crt1.o /usr/lib/gcc/x86_64-redhat-linux/5.3.1/../../../../lib64/crti.o /usr/lib/gcc/x86_64-redhat-linux/5.3.1/crtbegin.o -L/usr/lib/gcc/x86_64-redhat-linux/5.3.1 -L/usr/lib/gcc/x86_64-redhat-linux/5.3.1/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-redhat-linux/5.3.1/../../.. c.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-redhat-linux/5.3.1/crtend.o /usr/lib/gcc/x86_64-redhat-linux/5.3.1/../../../../lib64/crtn.o

如您所见,这并不容易.请注意,在gcc信息页面中有关于collect2如何查找链接器程序的文档.但是根据这些文档,它看起来的第一个位置不是环境变量,也不是您可以在命令行上指定的内容(例如--linker).文档说,它看起来 first 是硬编码的链接器文件名".如果该文档正确无误,则要强迫它不要使用该链接程序(即,欺骗它),则必须重命名默认链接程序(例如,sudo mv /usr/bin/ld /usr/bin/ld.tmp-disable).

As you can see, that's not easy. Note there is documentation in the gcc info page about how collect2 looks for a linker program. But according to those docs, the first place it looks is not an environment variable or something you can specify on the command line (e.g., --linker). The docs say it looks first for a "a hard coded linker file name". If that documentation is correct, to coerce it not to use that linker (i.e., trick it), you would have to rename the default linker (e.g., sudo mv /usr/bin/ld /usr/bin/ld.tmp-disable).

更新2 :使用-B似乎可以很好地满足我的需求.请参阅下面我发布答案的地方.我不能接受自己的回答,但如果可以的话,我会的-似乎很好地解决了这个问题.

Update 2: Using -B seems to work well enough for my needs. See below where I posted an answer. I can't accept my own answer, but I would if I could - it seems to solve the issue well.

推荐答案

通过-B选项,您可以为可执行文件,库,包含文件&编译器将使用的数据文件.对于某些版本的gcc [1]和clang(当前未记录-至少clang 3.7& 3.8的手册页)有效:

The -B option allows you to specify an alternate search path for executables, libraries, include files & data files that the compiler will use. This works for some versions of gcc [1] and for clang (currently undocumented - in man pages of at least clang 3.7 & 3.8):

cc -B/usr/local/bin foo.c -o foo

请注意,这将导致cc在-B指定的路径中搜索其他工具(例如,汇编器).因此,假设您在/usr/local/bin中安装了其他版本的binutils,如果仅 要使用该链接器(而不是/usr/local/bin/as等),则可以执行一些操作像这样:

Note that this will cause cc to search for other tools (e.g., the assembler) in the path specified by -B. So supposing you have a different version of binutils installed in /usr/local/bin, if you only want to use that linker (rather than /usr/local/bin/as, et. al.), you could do something like this:

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有多兼容.如前所述,clang手册页中目前未对此进行记录.但是它运行良好,足以让我选择一个替代链接器,如上所示.

-B has its own set of rules that allow you to override different files that the gcc compiler tries to use (programs, libraries, include files, data files). This is documented as far back as at least gcc 2.95 - read the gcc man / info pages. I don't know how compatible the behavior of -B is for clang. As mentioned, it's not currently documented in the clang man page. But it worked well enough to allow me to select an alternate linker as shown above.

gcc还支持调用-wrapper指定的脚本/程序. clang没有(当前).您也可以使用它并指向一个包装脚本,该脚本会更改编译器正在调用的程序.我不知道collect2是否会注意-wrapper选项(对于gcccollect2是至少在编译c/c ++程序时称为链接程序的东西.)

gcc also supports calling a script/program as specified by -wrapper. clang does not (currently). You could also use that and point at a wrapper script that alters what program the compiler is calling. I don't know if collect2 heeds the -wrapper option (and for gcc, collect2 is what calls the linker when compiling c/c++ programs at least).

[1]在gcc信息页中针对collect2记录的链接器搜索顺序表示,如果GCC是使用'--with-ld'选项配置的,它将首先搜索硬编码的链接器文件名". ").因此,如果您的gcc未配置'--with-ld',则它将最终在-B指定的路径中搜索(如果未首先找到real-ld).如果您的gcc 配置了--with-ld,则-B选项将无法帮助您指定所选的备用链接器.

[1] The linker search order documented in the gcc info page for collect2 says that it will search first for "a hard coded linker file name if GCC was configured with the '--with-ld' option"). So if your gcc was not configured with '--with-ld', then it will eventually search in the path specified by -B (if it doesn't find real-ld first). If your gcc was configured with --with-ld, then the -B option will not help you specify an alternate linker of your choosing.

这篇关于与"cc"链接时如何指定备用链接器命令的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆