GCC或G++在编译链接时,如果命令行中含有库,则要特别注意了。根据《C专家编程》5.3节中的提示,GCC在链接时对命令行时的处理顺序是从左到右。证据是GCC的MAN:
-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 -o program program.o libfoo.a
和
gcc -o program libfoo.a program.o
其中,libfoo.a库中包含program.o需要的链接函数。第一个命令行是正确的,第二个命令行是错误的。第二个命令是错误的原因是因为:GCC是先看到libfoo.a然后再看到program.o。当它看到libfoo.a时,因为libfoo.a没有任何缺失的函数链接,直接略过,在这里不做任何动作。当GCC看到program.o时,找到了一些未定义的函数,GCC想要继续分析命令行看是否有这些未定义函数的实现,却发现命令行已经结束了,因此,GCC发出了抱怨。
所以,一般来说,我们通常应该把命令行中最基本的库放在最后面。
但是,如果命令行中有两个库,这两库互相引用声明,这个问题该怎么办?
文献[1]给出了一种解决方法:用-Xlinker和-( archives -)来指定命令行中的库,例如:
gcc -o output.bin -Xlinker "-(" liba.ar libb.ar -Xlinker "-)" -lrt
该命令行执行可以让liba.ar libb.ar并行链接,从而解决互相引用问题。之所以这里要用-Xlinker,是因为GCC是不懂"-("与"-)"的,用-Xlinker可以让GCC忽略它。
文献[2]是GCC中文手册。
Reference:
- http://www.cppblog.com/findingworld/archive/2008/11/09/66408.html
- http://read.pudn.com/downloads127/doc/537629/GCC.pdf