链接器如何知道链接在一起的哪些档案?

时间:2011-12-14 13:58:43

标签: gcc linker

假设我正在使用GCC编译一个简单的 Hello World 程序。

当使用gcc -v hello-world.c运行时,我们可以从输出中获取生成ELF二进制文件的最后一行:

/usr/libexec/gcc/x86_64-pc-linux-gnu/4.5.3/collect2 --eh-frame-hdr -m
elf_x86_64 -dynamic-linker /lib64/ld-linux-x86-64.so.2
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../lib64/crt1.o
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../lib64/crti.o
/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/crtbegin.o
-L/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../lib64 -L/lib/../lib64 -L/usr/lib/../lib64 -L/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../x86_64-pc-linux-gnu/lib
-L/usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../.. /tmp/ccRykv97.o -lgcc --as-needed -lgcc_s --no-as-needed -lc -lgcc --as-needed -lgcc_s --no-as-needed /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/crtend.o /usr/lib/gcc/x86_64-pc-linux-gnu/4.5.3/../../../../lib64/crtn.o

从这个输出中我们可以看到像crtbegin.ocrtend.o这样的对象被链接在一起。但链接器如何知道这些文件应该链接到togeter?

一个单独但类似的问题是,如果我不想使用标准C库,当给定包含这些函数定义的目标文件目录时,如何知道传递给它们所需的文件链接器,以便它不会抱怨未知符号?

1 个答案:

答案 0 :(得分:3)

  

我们可以从输出中获取生成ELF二进制文件的最后一行

实际上不是生成ELF二进制文件的实际命令。 collect依次调用ld,而 命令会生成二进制文件。

  

链接器如何知道这些文件应该链接

没有。 GCC 告诉它(通过在命令行上提供它们)。

GCC有一个编译好的specs文件,它是一个特定于域的语言小程序,告诉GCC它应该为链接器提供什么参数。

您可以使用specs检查内置gcc -dumpspecs。您会发现该程序实际上非常复杂,crtbegin.o仅在-static-pie-shared未使用时使用。 -shared隐含crtbeginS.o-static隐含crtbeginT.o

  

如果我不想使用标准C库

在这种情况下使用-nostdlib标志。

  

给定一个包含这些函数定义的目标文件目录,如何知道传递给链接器所需的文件

定义您使用的函数的那些。 This可能有帮助。