gcc库的链接顺序和依赖问题

GCC在链接库时,库的顺序至关重要。如果库之间存在依赖,应当将被其他库调用的库放在后面。例如,由于libm中的log函数依赖libc中的__errno变量,链接顺序应为-lm -lgcc -lc。实际应用中,如liblog4cxx.a依赖libapr.a,libapr.a依赖libaprutil.a,libaprutil.a依赖libexpat.a,链接顺序应为liblog4cxx.alibapr.alibaprutil.alibexpat.a。理解这一原则能避免函数找不到定义的问题。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

gcc在链接库时,如果库之间 有依赖顺序,应该把被上层依赖的库放在后面

参考

https://www.cnblogs.com/ironx/p/4939508.html

gcc库的链接顺序,官方是这么解释的:

https://gcc.gnu.org/onlinedocs/gcc-5.2.0/gcc/Link-Options.html#Link-Options

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.

这句话翻译过来的意思就是说,如果你的库在链接时安排的顺序是:foo.o -lz bar.o。那么gcc的链接器先搜索库foo,然后是z库,然后是bar库。

这样就带来一个问题,如果库bar调用了库z里面的函数,但是链接器是先搜索的库z,这时候并没有发现库bar调用库z啊,所以就不会把库z中的这部分函数体挑出来进行链接。

而是只把库z中,被foo库调用的函数体挑出来。

 

回到我们之前的描述。

由于__errno全局变量是定义在库libc中,而库libm中的log函数会访问__errno全局变量。这就要求链接时,libm在libc的前面。所以我们应该这样安排库的链接顺序:

 -lm -lgcc -lc 

一句话,越是被别人调用的越底层的库,就越放在后面;越是调用别人的越上层的库,就越放在前面。

 

实际应用中,在编译时用的liblog4cxx.a时 ,依赖libapr.a库,libapr.a库又依赖libaprutil.a库,libaprutil.a又依赖libexpat.a库,在g++ Makefile文件的顺序应该是liblog4cxx.a libapr.a libaprutil.a libexpat.a

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值