前言
通常在安装一些开源的软件包时,经常会提示 no such #include portaudio.h file 相关异常,出现该问题是由于没有安装 portaudio 相关的软件,在Centos下通常可以使用 yum whatprovides */portaudio.h 来查看该文件是属于那个软件包所包含的头文件。
但是,通常也会有不生效的时候,比如我们明明装了 portaudio 相关软件,并且使用find命令可用查看到系统中包含 portaudio.h 的文件,但依然是报最初的错误。这是因为用户在安装程序的时候,程序去默认的头文件路径没有找到相关的头文件,通常这种情况会出现在用户自定义安装一些包所造成的,那么怎么处理呢?接下来总结下C系列语言下的头文件和库文件。
Linux下的动态链接库
通常编译C或C++程序时会使用如下方式加入额外函数库:
$ gcc sin.c -lm -L/lib -L/usr/lib
注意:使用gcc编译所加入的-lm是非常有意义的。
-l:是加入某个函数库(library)的意思
-m:是libm.so这个函数库,其中lib与扩展名(.a或.so)不需要写
后面的-L则表示去哪里查找相关的函数库。
- -L:表示用户需要的libm.so请到/lib或者/usr/lib里面去寻找
需要注意的是,在编译的时候,程序对库文件的查找也是有一定顺序和规则的:
gcc优先回去找-L指定的目录
然后找gcc的环境变量
LIBRARY_PATH再找内定目录
/lib、/usr/lib、/usr/local/lib
Linux下的include头文件
一般而言,在c语言编写的源文件中都会有#include <xxx.h>,这表示一些函数库需要由xxx.h文件读入,通常Linux下的一些头文件默认会放置在/usr/include/,但是如果没有依赖的一些头文件是用户自定安装的,我们就需要手动指定程序查找的头文件路径:
$ gcc sin.c -lm -I/usr/include
需要注意的是,gcc在编译程序时会去按照一定规则和顺序查找所需要的头文件:
优先搜索-I指定的路径
找GCC的环境变量
C_INCLUDE_PATH、CPLUS_INCLUDE_PATH、OBJC_INCLUDE_PATH去Linux默认的目录查找:/usr/include、/usr/local/include、/usr/lib/gcc/x86_64-redhat-linux/4.4.4/include
如果在安装GCC的时候指定了PREFIX的话,头文件会存放在$PREFIX/include下面。
程序运行时动态链接库的搜索路径
一般,在安装程序完(如libnet或mysql)使用过程中可能会出现 error while loading shared libraries: libnet.so.1:cannot open shared object file: no such file or directory 则表示共享库路径配置不正确,而程序运行时加载动态链接库的顺序如下,可以根据相关场景进行修复该问题。
在编译目标代码时指定改程序的动态链接库搜索路径(也可在编译目标代码时指定程序的动态库搜索路径)
通过环境变量
LD_LIBRARY_PATH指定动态搜索路径在配置文件
/etc/ld.so.conf指定动态链接库搜索路径;使用ldconfig命令进行加载动态库从默认的动态库中搜索
/lib、/usr/lib
需要注意的是,有时候在环境变量内部配置了LD_LIBRARY_PATH 仍然无法找到相关的动态链接库文件,这个时候需要检查/etc/ld.so.conf.d/ 目录下相关的库文件配置路径,有可能会和已有的配置产生冲突。
比如我们在使用pysoundfile的时候会使用到libsndfile.so模块,这些模块我们本身是配置在LD_LIBRARY_PATH,但是pysoundfile内部使用find_library 来进行查找模块的,而find_library的使用官网是这么介绍的:
https://docs.python.org/2/library/ctypes.html:
On Linux, find_library() tries to run external programs (/sbin/ldconfig, gcc, and objdump) to find the library file. It returns the filename of the library file. Here are some examples::
>>> from ctypes.util import find_library>>> find_library("m")'libm.so.6'>>> find_library("c")'libc.so.6'>>> find_library("bz2")'libbz2.so.1.0'>>>
ldconfig命令详情:http://man.linuxde.net/ldconfig
解决方案:
# source /export/data/jdder/speech/setenv.sh]# pythonPython 2.7.13 |Continuum Analytics, Inc.| (default, Dec 20 2016, 23:09:15)[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux2Type "help", "copyright", "credits" or "license" for more information.Anaconda is brought to you by Continuum Analytics.Please check out: http://continuum.io/thanks and https://anaconda.org>>> import soundfileTraceback (most recent call last):File "<stdin>", line 1, in <module>File "/export/data/jdder/speech/conda/py27/lib/python2.7/site-packages/soundfile.py", line 142, in <module>raise OSError('sndfile library not found')OSError: sndfile library not found# ln -s /export/data/jdder/speech/conda/py27/lib/libsndfile.so.1.0.27 /usr/lib64/libsndfile.so# pythonPython 2.7.13 |Continuum Analytics, Inc.| (default, Dec 20 2016, 23:09:15)[GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux2Type "help", "copyright", "credits" or "license" for more information.Anaconda is brought to you by Continuum Analytics.Please check out: http://continuum.io/thanks and https://anaconda.org>>> import soundfile
