【问题标题】:How to determine which command line options gcc passes to ld by default?如何确定 gcc 默认传递给 ld 的命令行选项?
【发布时间】:2013-01-03 07:17:22
【问题描述】:

考虑 hello world C 程序:

hello.c

#include "stdio.h"

int main()
{
        printf("Hello, World!\n");
}

如果我打电话:

$ gcc -c hello.c -o hello.o

它将生成一个 ELF 可重定位文件 hello.o

如果我再打电话:

$ gcc hello.o -o hello            [1]

它将 hello.o 与 ld 链接并生成一个 ELF 可执行文件 hello

但是,如果我直接调用 ld [2] 而不是 [1]

$ ld hello.o -o hello             [2]

我收到以下错误:

/usr/bin/ld.bfd.real: warning: cannot find entry symbol _start
test.c:(.text+0xa): undefined reference to `puts'

gcc 必须将其他选项传递给 ld(例如链接 C 库)。

有没有办法确定命令行 gcc 在命令 [1] 中传递给 ld 的确切内容?

【问题讨论】:

    标签: c linux gcc binutils


    【解决方案1】:

    是的,您可以使用gcc -v hello.o -o hello 来获取链接行。对于您在我的 ubuntu 机器上的示例,我得到了这个链接行(为了便于阅读,编辑为多行):

    /usr/lib/gcc/x86_64-linux-gnu/4.4.5/collect2
    --build-id
    --eh-frame-hdr
    -m elf_x86_64
    --hash-style=gnu
    -dynamic-linker
    /lib64/ld-linux-x86-64.so.2
    -o hello
    -z relro
    /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crt1.o
    /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crti.o
    /usr/lib/gcc/x86_64-linux-gnu/4.4.5/crtbegin.o
    -L/usr/lib/gcc/x86_64-linux-gnu/4.4.5
    -L/usr/lib/gcc/x86_64-linux-gnu/4.4.5
    -L/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib
    -L/lib/../lib
    -L/usr/lib/../lib
    -L/usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../.. -L/usr/lib/x86_64-linux-gnu
    hello.o
    -lgcc
    --as-needed -lgcc_s --no-as-needed 
    -lc
    -lgcc
    --as-needed -lgcc_s --no-as-needed
    /usr/lib/gcc/x86_64-linux-gnu/4.4.5/crtend.o
    /usr/lib/gcc/x86_64-linux-gnu/4.4.5/../../../../lib/crtn.o
    

    请注意,collect2 只是 ld 的别名。

    【讨论】:

    • 在我的 Ubuntu 12.10 64 机器上,collect2 似乎不是 ld 的简单别名。 collect2 是一个可执行文件,而ld 是指向ld.bfd 的符号链接,hardened-ld 是一个perl 脚本的符号链接。不知道那里发生了什么。
    • 对不起,我不是指文字别名。您会发现,如果您使用 ld 运行相同的命令,但它的工作方式相同。文档:gcc.gnu.org/onlinedocs/gcc-4.3.5/gccint/Collect2.html
    • collect2ld 有什么区别?读完 gccint 后不太容易理解。
    • 它们实际上是相同的二进制文件。
    【解决方案2】:

    对于在线爱好者:

    echo "int main(void) {}" | gcc -o /dev/null -v -x c - &> /dev/stdout| grep collect | tr -s " " "\012"
    

    -x c 替换为-x c++ 以获取c++ 标志。

    也可以与 clang 一起使用,但在这种情况下,您应该使用 grep 查找 /usr/bin/ld

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-09-11
      • 1970-01-01
      • 2016-11-05
      • 2016-12-29
      • 1970-01-01
      • 2015-10-13
      相关资源
      最近更新 更多