分开编译之后
一个文件可以定义函数,另一个文件只留下对该函数的引用。链接器读入目标文件和归档库,连接符号的定义与引用,并处理需要按最终布局调整的地址位置。
因此,单个源文件已经编译成功,并不保证整个程序能够链接成功。拼写不同的符号、缺少的库或不兼容的输入格式,都可能使连接程序各部分的工作失败。
布局也是输入的一部分
GNU ld 的链接脚本可以规定输入节如何进入输出节。官方示例把各文件的 .text 合并为代码区,再分别安排 .data 和 .bss,位置计数器决定未另行指定的输出地址。
这使链接器不只是把文件首尾拼接。符号、节、地址和目标格式共同决定结果;嵌入式程序等需要固定布局的场景,可以把这些要求写成脚本交给链接器。
参考:[2]
格式、驱动程序与全程序优化
LLD 为 ELF、PE/COFF、Mach-O 和 WebAssembly 等格式提供不同链接实现。通常由编译器驱动程序调用链接器,因为驱动程序还知道目标平台所需的启动文件和运行库。
启用链接时优化后,链接器可以接收编译器中间代码,让代码生成利用跨文件信息。这扩展了链接阶段的工作,但并不意味着链接器会重新理解任意源语言,也不意味着不同平台的二进制接口可以混用。
参考:[3]