假设我正在使用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)已链接在一起。但是链接器如何知道这些文件应该链接到geter?

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

最佳答案

我们可以从生成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可能会有所帮助。

关于gcc - 链接器如何知道将哪些文件链接在一起?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/8505682/

10-10 18:23
查看更多