gcc g++ 链接库的坑
假设我们需要用到两个静态库:libtest1.a和libtest2.a,其中libtest2.a中又使用了libtest1.a中的接口。
那么我们可以这样使用:(原来三种使用方式中的1、2其实是一种,后面只列出其中之一)
1. gcc –o test main.c libtest2.a libtest1.a
2. gcc -o test main.c -Xlinker “-(" libtest1.a libtest2.a -Xlinker “-)"
需要注意的是:第一种使用方式中静态库出现的顺序,libtest2.a必须在libtest1.a之前,否则会有"undefined reference to ***”的链接错误,其中***就是libtest2.a中使用的libtest1.a的接口。
如果libtest1.a在前,为什么会有链接错误呢?
原因是gcc在链接的时候,对于多个静态库或者.o文件是从前往后依次处理的,如果当前的静态库或.o文件中没有使用的符号,则往后继续寻找,而不会再往前查找。
下面是man gcc看到的说明:
|
1
2
3
4
5
6
7
|
-l library Search the library named library when linking. (The second alternative 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. |
所以在使用一些依赖关系比较复杂的静态库时,我们可能会看到这样的使用方式:gcc –o test main.c libtest1.a libtest2.a libtest1.a。在链接序列中,一个静态库可能出现多次,以解决一些循环依赖。
那么如果是gcc -o test main.c -Xlinker “-(" libtest1.a libtest2.a -Xlinker “-)"的使用方式,还需要考虑顺序么?
答案是不需要。
因为Xlinker选项是将参数传给链接器,而man ld我们可以看到这样一段说明:
|
1
2
3
4
5
6
7
8
9
10
11
12
|
-( 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. <strong>The specified archives are searched repeatedly until no new undefined references are created.</strong> 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 pos- sible 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. |
链接器在处理”-(”和”-)”之间的静态库时,是会重复查找这些静态库的,所以就解决了静态库查找顺序问题。不过,man里面也说明了,这种方式比人工提供了链接顺序的方式效率会低很多。
浙公网安备 33010602011771号