Joh*_*itb 11 linker static-libraries unix-ar .a
如果在一个构建脚本中构建静态库,并且想要在链接最终可执行文件时使用这些静态库,则提示.a文件的顺序非常重要:
g++ main.o hw.a gui.a -o executable
Run Code Online (Sandbox Code Playgroud)
如果gui.a使用hw.a链接中定义的内容将失败,因为在hw.a处理时,链接器尚不知道稍后需要该定义,并且不将其包含在is.generated可执行文件中.与连接线手动摆弄周围是不实际的,所以解决方案是使用--start-group和--end-group它通过库使得连接器运行两次,直到没有未定义的符号被发现了.
g++ main.o -Wl,--start-group hw.a gui.a -Wl,--end-group -o executable
Run Code Online (Sandbox Code Playgroud)
然而,GNU ld手册说
使用此选项会产生显着的性能成本.最好只在两个或多个档案之间存在不可避免的循环引用时才使用它.
所以我认为最好把所有.a文件放在一个.a带有索引(-sGNU ar选项)的文件中,该文件说明文件需要链接的顺序.然后只给出一个.a文件g++.
但我想知道这是否比使用组命令更快或更慢.这种方法有什么问题吗?我也想知道,有没有更好的方法来解决这些相互依赖问题?
编辑:我编写了一个程序,它接受一个.a文件列表并生成一个合并.a文件.使用GNU通用ar格式.将LLVM的所有静态库打包在一起就像这样工作
$ ./arcat -o combined.a ~/usr/llvm/lib/libLLVM*.a
Run Code Online (Sandbox Code Playgroud)
我将速度与.a手动解.a压缩所有文件进行比较,然后使用ar重新计算索引将它们放入新文件中.使用我的arcat工具,我获得大约500毫秒的一致运行时间.使用手动方式,时间变化很大,大约需要2秒.所以我认为这是值得的.
代码就在这里.我把它放到公共领域:)
是否还有第三种选择,您只需构建一个库即可开始?我遇到了类似的问题,最终决定采用第三种选择。
根据我的经验,分组比统一 .a 文件要慢。您可以从存档中提取所有文件,然后从较小的文件中创建一个新的 .a 文件
但是,您必须小心两个文件碰巧包含相同定义的情况(您可以通过使用来显式检查nm每个库中包含哪些定义)