我们可以认为静态库的最小链接单位是静态库所打包的单个object file
文件。
链接器驱动程序(如gcc
)会维护一个可重定位目标文件集合E,未解析符号集合U,位于之前已输入的文件中的已定义符号集合D。
对于存档文件(静态库)链接器会尝试匹配U中未解析的符号和存档文件中的目标文件成员的符号(静态库类似于将一些object file打包为一个文件)。如果这个成员目标文件中链接器就会把这个目标文件成员加到E,再修改U和D来反映这个目标文件成员的符号定义和引用。遍历存档文件中的所有成员目标文件,遍历完毕所有未被包含在E中的成员目标文件就会简单地被丢弃。
(CS:APP一书“链接”章节部分的个人概述。)
简单来说,静态库所打包的多个object file
只会按需(按照之前被链接的源码的未定义符号需求)、以单个文件为单位链接。这意味着如果在一个大型项目中,一个目标文件中包含了多个函数,而在这些函数之中只有少数几个符号被引用,则整个目标文件会被静态链接进可执行程序,最终导致可执行程序较大。
这也是glibc会尽可能把每个函数拆分为独立的.o
文件并打包为libc.a的原因之一。
可以使用
ar t /usr/lib/x86_64-linux-gnu/libc.a
(debian系)
ar t /usr/lib/libc.a
查看