1。头文件的位置
gcc默认会在/usr/include目录下寻找头文件,这是标准库的头文件的路径,但非标准的库一般不会把头文件直接放在该目录下,一般的作法是在该目录下创建一个自己的目录,然后在此目录下直接或分门别类(即再创建更深层次的目录,gtk+即一例证)放自己的头文件。如果是这样,gcc编译时是不会找到这些头文件的,我们会看到有“×××: No such file or directory”的出错信息。解决的方法就是用gcc的-I选项列出这些非标准的路径(实际编程当中一般是由pkg-config --cflags 完成这一工作的)。
2。库的位置
gcc默认会链接标准c语言库,但如果所用的库是“舶来品”,gcc自然不会自动链接,如果也没有显式链接的话,在链接阶段就会出现诸如“: undefined reference to `gtk_container_set_border_width'
/tmp/ccvHaxUx.o(.text+0x1af): In function `main':”的错误。 解决的方法就是利用gcc的-l参数显式链接需要链接的库。这样gcc就会按照一种特定的命名规则到默认的目录(/usr/lib和/lib等目录)下去寻找这些库,并自动链接。但如果库放在自己的定义的目录下,gcc还是不能找到的,这种情况下可以用gcc -L来列出非标准库的路径。实际编程中这一工作是由pkg-config --libs完成的。
上面两次提到pkg-config命令,各位可能就会有疑问了:难道pkg-config前知八百年,后知八百年,无所不能?非也,其实pkg-config也有自己的一套规则来提供关于所查询库的信息。
当要查询指定库(如gtk+-2.0库)的信息时,我们要以gtk+-2.0为参数运行pkg-config命令(如pkg-config --libs --cflags gtk+-2.0)。此时,pkg-config会到默认目录(如/usr/lib/pkgconfig目录)以及PKG_CONFIG_PATH指定的目录去找一个配置文件,该文件就记录了所查询的库在该系统上信息。该配置文件的命名规则是:所查询库的名字加上后缀.pc。若要查询gtk+-2.0的信息,则pkg-config会按上面所说的寻找gtk+-2.0.pc。如果找到,万事大吉,直接根据找到的文件的内容显式库的信息。如果找不到以.pc为后缀的配置文件,则显示出错信息提示用户继续寻找。例如:
[leo@leo ~]$ pkg-config --libs --cflags gtkmm-2.0
Package gtkmm-2.0 was not found in the pkg-config search path.
Perhaps you should add the directory containing `gtkmm-2.0.pc'
to the PKG_CONFIG_PATH environment variable
No package 'gtkmm-2.0' found
这就有两种可能:一是gtkmm-2.0.pc没有放在/usr/lib/pkg-config下。二就是gtkmm-2.0根本就没有装。
对应的解决方法:第一种情况直接用find,locate等命令把gtkmm-2.0.pc找出来,把路径加入环境变量PKG_CONFIG_PATH中,再运行命令pkg-config --libs --cflags gtkmm-2.0。第二种情况就只能安装gtkmm-2.0库了。
关pkg-config的更详细的用法请参加pkg-config的manpage:)
如前所述,当显式链接库时,gcc会按自己的规则去寻找库的名字,现在就来说说库的命名规则。
系统中的库分两类,静态库和动态库(关于动态库和静态库的区别以及如何添加自己的库,请参看我在blog上的另一篇文章)。静态库和动态库在命名上的区别就是后缀名不同而已。动态库以.so(意为shared object)结尾,而静态库一.a(意为archive)结尾。由于种种原因,链接时是优先链接动态库的,如果不成功,则链接静态库。
除了有相区别的后缀外,动态和静态库都有相同的前缀lib,这样动态库就有形如libXX.so的形式,相应的,静态库的名字看起来会是这样libXX.a。
比如,用-lm参数链接数学库时,gcc就会去寻找libm.so或libm.a。
文章来源于领测软件测试网 https://www.ltesting.net/