我的一位同事昨天告诉我,构建libfoo.a不需要定义所有函数,只要它们构建一个链接到它的可执行文件并且定义了缺少的引用即可。
他说档案只是具有索引的目标文件的集合,并且由于目标文件可以使用未定义的引用构建,因此可以归档..
这是真的吗?如果是这样,这是否意味着仅在链接阶段(即从未编译或存档)执行引用解析?
非常感谢..编译器就是gcc,语言是c / c ++
答案 0 :(得分:4)
是的,这一切都是完全正确的。你似乎知道libfoo.a
是ar
存档。 ar
是GNU
通用归档器。存档内容非常高兴
您的文档,图片和/或音乐文件夹作为对象的集合
文件。
外部符号解析是联动:它是联动和联动的核心业务
仅由链接器完成。如果ar
应该解析归档中目标文件的外部符号引用,那么ar
,
像链接器一样,需要命令选项来指定外部库
要搜索哪些符号定义,以及其中的目录
这些图书馆将被搜索。它没有。
ar
存档可用作链接器输入文件。在这种情况下,链接器将
在存档中搜索提供未解析定义的任何目标文件
已经消耗的目标文件累积的符号引用。它会
不关心归档中的其他类型的文件,用或
没有目标文件。如果找到任何定义未解析引用的目标文件,则会提取
它们来自存档并将它们添加到链接中,就像它们是单独的一样
在命令行中指定,并且根本没有提到存档。所以唯一的作用
链接中的存档是一个目标文件包,链接器可以从中选择一个
它需要继续下去。
如果我们知道提供链接器的合适包,我们就不用担心
确切地说,链接中需要哪些目标文件。这是有用的
静态库。原则上,可能已采用任何存档格式(.tar
,.gz
...)但ar
是第一个
这个领域没有不必要的功能(目录序列化,压缩...),并且是历史的选择。
顺便提一下,Microsoft LIB
格式与ar
格式相同。
对于链接器服务中的这个角色,GNU ar
专门用了一点
存在目标文件。 s
选项 - 这是默认选项,可以覆盖
S
- 在档案库中添加一个虚假的“文件”,文件名为空,数据为
链接器能够从归档中的任何目标文件定义的全局符号读取为查找表
这些目标文件的名称和位置。以前
(在ar
的非GNU变体中)这个kludge是通过单独运行来应用的
程序,ranlib
在存档上,以使链接器可以访问它。
注入ranlib表使链接器能够从归档中选择所需的目标文件。
使用这些目标文件引入的任何未定义引用都是链接器引用的
像往常一样解决后续使用的目标文件或库。
您的问题的措辞表明您可能会认为“归档” -
例如创建libfoo.a
- 是可以调用的进程之一,如编译
和联系,通过GCC前端(gcc
,g++
,gfortran
等)这不是
所以。这些前端仅调用(一个或多个)预处理器,编译器和汇编器
和链接器。档案是提供目标文件的辅助便利
到链接器并使用ar
:
ar cr libfoo.a file.o...
完成此操作后,libfoo.a
中的未定义引用就是
file.o ...
中的未定义引用。