编译链接的时候静态库顺序导致符号未定义问题详解

本文探讨了在C++编译链接过程中,静态库顺序如何影响符号未定义问题。通过实验分析,揭示了静态库由.o文件组成,链接时按从左到右顺序处理,并不回溯的策略。同时,指出在Mac上使用clang++编译可能不会有此类问题。文章通过不同情况的示例,解释了符号未定义错误的原因,并提出将所有文件打包到一个静态库可以避免顺序问题。
摘要由CSDN通过智能技术生成

前情概要

接入新库的时候遇到符号位定义问题。有人跟我说改一下库的顺序,就能解决问题。我试了下,嗯,问题是解决了。但是我总觉得库之间不应该有依赖关系,毕竟链接库就是个找符号的问题,如果有依赖,那a,b两个库,相互依赖,顺序怎么整呢?大型的软件,岂不是加一个库就要弄死人?带着这个疑问我做了一些小实验,来看一下一下库位置的顺序到底是如何影响符号未定义问题的。

问题根源

之所以链接顺序改变可以解决符号未定义问题,本质是因为以下两点导致的:

  1. 静态库是由.o文件拼出来的,链接静态库的时候,是以.o文件为单位进行的。

  2. 我们开发,编译机上,gcc/g++在进行链接的时候,使用的是从左到右,逐个文件处理,并且不走回头路的策略。

另外这个行为与编译器有关,在mac上用clang++测试,是没有这些问题的,顺序怎么打乱,都能链接上(确实没有符号定义的除外)。具体是上面哪个因素被打断,目前不确定,以后有需要的时候再研究吧。

我使用下面这个makefile和main.cpp,然后使用a,b,c,d四个cpp文件进行示例分析。注意,每个情况都是独立的a,b,c,d四个文件,不需要的时候你可以随意往文件里写个不相干的函数,不影响结果。不要弄混。

void hello();

int main(int argc, char *argv[])

{

    hello();

    return 0;

}
a.out: libab.a libcd.a

    - g++ main.o libab.a libcd.a

    - g++ main.o libcd.a libab.a





libab.a: a.o b.o

    ar csr libab.a a.o b.o





libcd.a: c.o d.o

    ar csr libcd.a c.o d.o





main.o: main.cpp

    g++ -c main.cpp

a.o: a.cpp

    g++ -c a.cpp

b.o: b.cpp

    g++ -c b.cpp

c.o: c.cpp

    g+&#
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值