如果在构建脚本中构建静态库,并且想要在链接最终可执行文件时使用这些静态库,则提到.a
文件的顺序很重要:
g++ main.o hw.a gui.a -o executable
如果gui.a
使用了hw.a
中定义的某些内容,链接将会失败。这是因为在处理hw.a
时,连接器不知道稍后需要这个定义,并且没有在生成的可执行文件中包含它。手动修改链接器行不太实际,因此一个解决方案是使用--start-group
和--end-group
,使连接器再次遍历库,直到不再找到未定义的符号为止。g++ main.o -Wl,--start-group hw.a gui.a -Wl,--end-group -o executable
然而GNU ld手册说:
使用这个选项会有显著的性能代价。只有在两个或多个存档之间存在不可避免的循环引用时,才最好使用它。
所以我认为将所有的.a
文件放在一起,并用带有索引的一个.a
文件来指示需要连接的文件顺序可能更好(-s
选项的GNU ar)。然后将这个.a
文件提供给g++
。
但我想知道这样做是比使用组命令更快还是更慢。 还有这种方法是否有任何问题? 我也想知道是否有更好的解决这些相互依赖问题的方法?
编辑:我编写了一个程序,可以获取.a
文件列表并生成合并的.a
文件。适用于GNU通用ar
格式。像这样打包LLVM的所有静态库:
$ ./arcat -o combined.a ~/usr/llvm/lib/libLLVM*.a
我将速度与手动解压所有.a
文件,然后使用ar
将它们放入新的.a
文件并重新计算索引进行了比较。使用我的arcat
工具,我得到了大约500毫秒的一致运行时间。而手动方法的时间变化很大,需要大约2秒钟。所以我认为这样做是值得的。
代码在这里。我已将其放入公共领域 :)
lorder
,但是我找不到它。我在互联网上只找到了几个man页面,上面写着lorder
已经被弃用,而ar
替代了它。我找不到应该给ar
什么命令才能实现与lorder
相同的功能。 - Johannes Schaub - litbbsdmainutils
软件包中。 - jilles