Linux C/C++ 链接选项之静态库--whole-archive,--no-whole-archive和--start-group, --end-group

Posted JimmyTY

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Linux C/C++ 链接选项之静态库--whole-archive,--no-whole-archive和--start-group, --end-group相关的知识,希望对你有一定的参考价值。

参照这两篇博客:

http://stackoverflow.com/questions/805555/ld-linker-question-the-whole-archive-option

http://codemacro.com/2014/09/15/inside-static-library/

这四个都是链接器的选项,所以在编译的时候要用-Wl,[options]来传递给链接器,不然编译器会不认得这个选项。

--whole-archive选项解决的是编译中常遇到的问题。在代码中定义的符号(如函数名)还未使用到之前,链接器并不会把它加入到连接表中。如下面这个例子:

a.cpp:

void func(){printf("I am in a.cpp.\n");}

main.cpp:

extern void func();

int main(){func(); printf("I am in main.cpp"); return 0;}

首先编译g++ -c a.cpp,再打包ar -r liba.a a.o。

如果这么链接g++ -L. -la main.cpp -o main,则链接器会报错,称func()未定义。其实改一下顺序既可以解决g++  main.cpp -L. -la -o main。

或者使用g++ -Wl,--whole-archive -L. -la -Wl,--no-whole-archive main.cpp -o main,将liba.a中的所有.o中的符号都链接进来。

对于C++中使用的Register机制,即动态对象创建会遇到这样的问题。在使用Caffe库的时候也遇到了这样的问题。

 

对于--start-group和--end-group, gcc liner man中如下描述:

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 undefined 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 symbol referred to by an object in an archive that appears later on the command line, the linker would not be able to resolve that reference. 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

这里有一个链接顺序的问题,在command line上前面的库会依赖之后的库,如果碰到循环链接,-lliba -llibb -lliba,这样就需要使用--start-group和--end-group反复在.a中进行搜索直到所有的未定义字符都被找到为止,而不是默认的只搜索一次。MKL库有这样的问题。

 

以上是关于Linux C/C++ 链接选项之静态库--whole-archive,--no-whole-archive和--start-group, --end-group的主要内容,如果未能解决你的问题,请参考以下文章

转载我使用过的Linux命令之ar - 创建静态库.a文件

zt:我使用过的Linux命令之ar - 创建静态库.a文件

CGO静态库和动态库

CGO静态库和动态库

cgo之调用静态库

如何编译C/Fortran动态/静态链接库