【转】gcc 编译链接库存在顺序问题…

使用gcc生成可执行文件时,大部分时候我们需要连接我们自己打包(AR)好的一些库文件,对于中大型(50万代码行以上)项目上,你将面对数个项目组, 最好的情况是每个项目组发布自己的打包.ar文件,这些.ar文件之间没有任何依赖关系, 然后由持续集成(ci)小组对这些包进行连接,不幸的是,这几乎是不可能的, 我们在连接时还是遇到了liba.ar和libb.ar相互依赖的情况。

因为gcc的库是个有点怪怪的特性,在看-l帮助时可以看到:
            -l library
                    Search the library named library when linking.  (The second alter-
                    native with the library as a separate argument is only for POSIX
                    compliance and is not recommended.)

                    It makes a difference where in the command you write this option;
           the linker searches and processes libraries and object files in the
           order they are specified.  Thus, foo.o -lz bar.o searches library z
           after file foo.o but before bar.o.  If bar.o refers to functions in
           z, those functions may not be loaded.

      出于知识产权保护的考虑,每一个项目组可能只允许看到自己的代码和别的项目组的头文件,这给CI小组带来了很头痛的事情,很多时候你不得不把库顺序来回调 整。我也遇到了这样让人崩溃的情形,问题是对于liba.ar和libb.ar相互以来的情形,你可能最终采取丑陋的做法,将其中一个库在前后放两次:
gcc -o out.bin liba.ar libb.ar liba.ar -lrt
否则,您将不得不面对 "xx not referenced"之类的错误。

看看gcc的帮助,有下面的选项
-Xlinker option
                    Pass option as an option to the linker.  You can use this to supply
                    system-specific linker options which GCC does not know how to rec-
                    ognize.

                    If you want to pass an option that takes an argument, you must use
                    -Xlinker twice, once for the option and once for the argument.  For
                    example, to pass -assert definitions, you must write -Xlinker
                    -assert -Xlinker definitions.  It does not work to write -Xlinker
                    "-assert definitions", because this passes the entire string as a
                    single argument, which is not what the linker expects.

也就是说,-Xlinker是将连接选项传给连接器的,赶快看看ld的帮助有没有解决库顺序的选项吧:
  -( archives -)
            --start-group archives --end-group
                    The archives should be a list of archive files.  They may be either
                    explicit file names, or -l options.

                    The specified archives are searched repeatedly until no  new  unde-
           fined  references  are  created.   Normally, an archive is searched
                    only once in the order that it is specified on  the  command  line.
                    If  a symbol in that archive is needed to resolve an undefined sym-
                    bol referred to by an object in an archive that  appears  later  on
                    the command line, the linker would not be able to resolve that ref-
                    erence.  By grouping the archives, they all be searched  repeatedly
                    until all possible references are resolved.

                    Using  this  option has a significant performance cost.  It is best
                    to use it only  when  there  are  unavoidable  circular  references
                    between two or more archives.


不错,我们有个有点怪异的选项,-(和-),它能够强制"The specified archives are searched repeatedly"
god,这就是我们要找的啦。

最终的做法:
gcc -o output.bin -Xlinker "-(" liba.ar libb.ar -Xlinker "-)" -lrt

这样可以解决库顺序的问题了!问题是,如果你的库相互间的依赖如果错综复杂的话,可能会增加连接的时间,不过,做架构设计的都应该能考虑到这些问题吧。

原文出自:http://www.cppblog.com/findingworld/archive/2008/11/09/66408.html#Post

另一个文章:http://www.cppblog.com/wiisola/archive/2010/05/18/115637.html

GNU GCC手册2:http://www.shanghai.ws/gnu/gcc_2.htm
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值