菠菜

敏感而豁达

g++使用第三方库编译时遇到的一个小问题

假设你有程序a.cpp,要使用第三方库libS.a,第三方库提供了头文件S.h。假定S.h中定义了很多函数,任意举一个例子,声明为void M1(int &)的方法。

因为你要调用M1方法,所以你会在a.cpp中加入#include S.h这么一行。

现在编译。Makefile中大概是这样写的:

a.o : a.cpp
	g++ -c a.cpp

a : a.o libS.a
	g++ libS.a –o a a.o

问题出来了,编译会报错,说undefined reference to ‘M1(int&)’

纳闷啊~~~

...

解决办法:

把libS.a的顺序放在最后,也就是改为g++ –o a a.o libS.a就好了。

为什么呢?

那一定是你没有认真看g++的帮助文档。其中关于库的使用中有如下说明:

-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.

The linker searches a standard list of directories for the library, which is actually a file named liblibrary.a. The linker then uses this file as if it had been specified precisely by name.

The directories searched include several standard system directories plus any that you specify with -L.

Normally the files found this way are library files---archive files whose members are object files. The linker handles an archive file by scanning through it for members which define symbols that have so far been referenced but not defined. But if the file that is found is an ordinary object file, it is linked in the usual fashion. The only difference between using an -l option and specifying a file name is that -l surrounds library with lib and .a and searches several directories.

注意一下上面的粗体字就知道原因了。所以,唉,想想真二。

 

好了,顺便提一下,怎么在Qt中引用第三方库呢,你只需要在.pro文件中加两行,类似

INCLUDEPATH += 你的第三方库头文件路径,如/home/a/b/include
LIBS += 你的第三方库文件路径,如/home/a/b/libS.a

posted on 2012-06-28 12:01  ~菠菜~  阅读(857)  评论(0编辑  收藏  举报

导航