前情概要
接入新库的时候遇到符号位定义问题。有人跟我说改一下库的顺序,就能解决问题。我试了下,嗯,问题是解决了。但是我总觉得库之间不应该有依赖关系,毕竟链接库就是个找符号的问题,如果有依赖,那a,b两个库,相互依赖,顺序怎么整呢?大型的软件,岂不是加一个库就要弄死人?带着这个疑问我做了一些小实验,来看一下一下库位置的顺序到底是如何影响符号未定义问题的。
问题根源
之所以链接顺序改变可以解决符号未定义问题,本质是因为以下两点导致的:
-
静态库是由.o文件拼出来的,链接静态库的时候,是以.o文件为单位进行的。
-
我们开发,编译机上,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+&#