【发布时间】:2011-10-26 13:18:46
【问题描述】:
如果一个人在自己的构建脚本中构建静态库,并且想要使用这些静态库来链接最终的可执行文件,那么提到 .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 文件中(GNU ar 的-s 选项),该索引说明文件需要按什么顺序排列链接。然后一个人只把那个.a文件给g++。
但我想知道这是否比使用组命令更快或更慢。这种方法有什么问题吗?我也想知道,有没有更好的方法来解决这些相互依赖的问题?
编辑:我编写了一个程序,它采用.a 文件列表并生成合并的.a 文件。适用于 GNU 通用 ar 格式。像这样将 LLVM 的所有静态库打包在一起
$ ./arcat -o combined.a ~/usr/llvm/lib/libLLVM*.a
我将速度与手动解压缩所有.a 文件然后使用ar 将它们放入一个新的.a 文件进行比较,重新计算索引。使用我的arcat 工具,我获得了大约 500 毫秒的一致运行时间。使用手动方式,时间变化很大,大约需要2s左右。所以我觉得值得。
Code is here。我把它放到公共领域:)
【问题讨论】:
标签: linker static-libraries unix-ar .a