前言
通常在安装一些开源的软件包时,经常会提示 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
]# python
Python 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 linux2
Type "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
Traceback (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
# python
Python 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 linux2
Type "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