如果一个人在自己的构建脚本中构建静态库并且想要使用这些静态库来链接最终的可执行文件,那么提到.a
文件的顺序很重要:
g++ main.o hw.a gui.a -o executable
如果gui.a
使用hw.a
链接中定义的某些内容将失败,因为在hw.a
处理时,链接器还不知道稍后需要该定义,并且不会将其包含在being.generated 可执行文件中。手动摆弄链接器行是不切实际的,因此使用一种解决方案--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
手动解压缩所有文件然后使用重新计算索引将它们放入新.a
文件进行了比较。ar
使用我的arcat
工具,我获得了大约 500 毫秒的一致运行时间。使用手动方式,时间变化很大,大约需要2s左右。所以我认为这是值得的。
代码在这里。我把它放到公共领域:)