今天在编译的时候遇到一个gcc编译链接库顺序的问题,描述如下:
$ gcc elements.c -o par -L/usr/lib -lparsifal
编译通过,但是如下编译时出错
$ gcc -L/usr/lib -lparsifal elements.c -o par
/tmp/ccO82iYg.o: In function `main':
elements.c:(.text+0xcb): undefined reference to `XMLParser_Create'
elements.c:(.text+0x143): undefined reference to `XMLParser_Parse'
elements.c:(.text+0x187): undefined reference to `XMLParser_Free'
collect2: ld 返回 1
两者不同指出就是链接库指定的顺序不同。
查了相关资料总结:
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.
看看gcc的帮助,有下面的选项
-Xlinker option
Pass option as an option to the linker. You can use this to supply
system-specific linker options which GCC does not know how to rec-
ognize.
If you want to pass an option that takes an argument, you must use
-Xlinker twice, once for the option and once for the argument. For
example, to pass -assert definitions, you must write -Xlinker
-assert -Xlinker definitions. It does not work to write -Xlinker
"-assert definitions", because this passes the entire string as a
single argument, which is not what the linker expects.
也就是说,-Xlinker是将连接选项传给连接器的,赶快看看ld的帮助有没有解决库顺序的选项吧:
-( 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.
The specified archives are searched repeatedly until no new unde-
fined 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 sym-
bol referred to by an object in an archive that appears later on
the command line, the linker would not be able to resolve that ref-
erence. 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.
最终的做法:
gcc -o output.bin -Xlinker "-(" la lb -Xlinker "-)" -lrt
上面的方法是解决了,库之间相互依赖的问题,但是没有解决我一开始发现的问题,
只能暂时总结为:
gcc 链接时优先选择从后面给出的库中找符号。
所以编译时应将链接库的指定放在后面。
参考文章:
http://www.cppblog.com/findingworld/archive/2008/11/09/66408.html