这两天一直在倒弄两个编译器的链接问题,这篇文章算是一个总结。
静态链接
假设一个程序 P 需要调用一个库 L,如果有着库 L 的源码,可以将 P 与 L 同时编译,生成一个 新的程序 N,其中 N = P + L (这里假设 L 全部被使用)。
由于各种原因,L 可能不开放源码。L 的作者可能会发布一个已经编译好的二进制文件 Lb,编译 P 结束后再将生成的 Pb 与 Lb 进行链接。新生成的程序 N = Pb + Lb。这里的 N 显然和上文的 N 是相近的存在。(与 Lb 的 编译 有关, 因为 L 可能 与 P 不是同样的方式进行编译。)
静态链接类似于,将目标程序分成几大部分来编译,最后进行一个完整的链接。这和直接从源码进行编译(每个文件单独编译,最后进行链接)其实是类似的。
GCC
生成静态链接库
GCC 生成静态链接库,其实是对库中各个源码文件生成的二进制文件进行打包(归档)。
假设库 L 包含以下文件:
a.h b.h c.h a.c b.c c.c
首先使用 GCC 编译生成多个 .o 文件:
gcc -c a.c b.c c.c
获得多个.o文件
a.o b.o c.o
然后将它们进行归档:
ar -r libL.a a.o b