假设我正在使用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.o
和crtend.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/