使用未定义的引用构建库存档

Build library archive with undefined references

我的一位同事昨天告诉我,构建 libfoo.a 不需要定义它的所有功能,只要您正在构建链接到它并定义它的可执行文件即可缺少参考..

他说归档只是带有索引的目标文件的集合,并且由于可以使用未定义的引用构建目标文件,因此归档也可以..

这是真的吗?如果是这样,这是否意味着引用解析仅在链接阶段执行(即从不在编译或归档阶段执行)?

非常感谢.. 编译器是 gcc,语言是 c/c++

是的,这一切都是千真万确的。你似乎知道 libfoo.a 是一个 ar 存档。 ar 是 GNU 通用存档器。存档内容一样开心 您的文档、图片 and/or 音乐文件夹作为对象集合 文件。

外部符号解析为联动:是联动的核心业务,联动 仅由链接器完成。如果 ar 应该解析存档中目标文件的外部符号引用,那么 ar, 像链接器一样,需要命令选项来指定外部库 要搜索哪些符号定义,以及其中的目录 将搜索这些库。没有。

ar 存档可用作链接器输入文件。在这种情况下,链接器将 在存档中搜索任何提供未解析定义的目标文件 从已消耗的目标文件中累积的符号引用。它会 根本不关心存档中还有哪些其他类型的文件,或者 没有目标文件。如果它找到任何定义未解析引用的目标文件,它会提取 从存档中将它们添加到链接中,就好像它们是单独的一样 在命令行中指定,根本没有提到存档。所以唯一的作用 链接中的存档就像一包目标文件,链接器可以从中挑选一个 它需要继续。

如果我们知道提供链接器的正确包,我们就可以避免了解的困难 链接将需要其中的确切目标文件。这就是用处 的静态库。原则上,任何存档格式都可能被采用(.tar.gz...)但是 ar 是第一个 该领域没有负担不需要的功能(目录序列化,压缩......),并且是历史的选择。 Microsoft LIB 格式,顺便说一句,与 ar 格式相同。

对于链接器服务中的这个角色,GNU ar 进行了一些专门化 目标文件的存在。 s 选项 - 这是一个默认值,可由 S - 添加一个假的 "file" 到档案中,文件名和数据为空 链接器能够从存档中任何目标文件定义的全局符号中读取 table 这些目标文件的名称和位置。以前 (并且在 ar 的非 GNU 变体中)这个 kludge 是由 运行 一个单独的 程序,ranlib 在存档上,以便链接器可以访问它。 ranlib table 的注入使链接器能够从存档中选择它需要的目标文件。 与这些目标文件一起引入的任何未定义引用供链接器使用 像往常一样从随后使用的对象文件或库中解析。

您问题的措辞表明您可能认为 "archiving" - 例如creating libfoo.a - 是可以调用的过程之一,如编译 和链接,通过 GCC 前端(gccg++gfortran 等)这不是 所以。这些前端仅调用(一个或多个)预处理器、编译器、汇编器 和链接器。归档是交付目标文件的辅助便利 到链接器并使用 ar:

直接创建
    ar cr libfoo.a file.o...

完成后,libfoo.a 中的未定义引用就是 file.o ....

中的未定义引用