前言

通常在安装一些开源的软件包时,经常会提示 no such #include portaudio.h file 相关异常,出现该问题是由于没有安装 portaudio 相关的软件,在Centos下通常可以使用 yum whatprovides */portaudio.h 来查看该文件是属于那个软件包所包含的头文件。
但是,通常也会有不生效的时候,比如我们明明装了 portaudio 相关软件,并且使用find命令可用查看到系统中包含 portaudio.h 的文件,但依然是报最初的错误。这是因为用户在安装程序的时候,程序去默认的头文件路径没有找到相关的头文件,通常这种情况会出现在用户自定义安装一些包所造成的,那么怎么处理呢?接下来总结下C系列语言下的头文件和库文件

Linux下的动态链接库

通常编译C或C++程序时会使用如下方式加入额外函数库:

  1. $ 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/,但是如果没有依赖的一些头文件是用户自定安装的,我们就需要手动指定程序查找的头文件路径:

  1. $ gcc sin.c -lm -I/usr/include

需要注意的是,gcc在编译程序时会去按照一定规则和顺序查找所需要的头文件:

  • 优先搜索-I指定的路径

  • 找GCC的环境变量 C_INCLUDE_PATHCPLUS_INCLUDE_PATHOBJC_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::

  1. >>> from ctypes.util import find_library
  2. >>> find_library("m")
  3. 'libm.so.6'
  4. >>> find_library("c")
  5. 'libc.so.6'
  6. >>> find_library("bz2")
  7. 'libbz2.so.1.0'
  8. >>>

ldconfig命令详情:http://man.linuxde.net/ldconfig

解决方案:

  1. # source /export/data/jdder/speech/setenv.sh
  2. ]# python
  3. Python 2.7.13 |Continuum Analytics, Inc.| (default, Dec 20 2016, 23:09:15)
  4. [GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux2
  5. Type "help", "copyright", "credits" or "license" for more information.
  6. Anaconda is brought to you by Continuum Analytics.
  7. Please check out: http://continuum.io/thanks and https://anaconda.org
  8. >>> import soundfile
  9. Traceback (most recent call last):
  10. File "<stdin>", line 1, in <module>
  11. File "/export/data/jdder/speech/conda/py27/lib/python2.7/site-packages/soundfile.py", line 142, in <module>
  12. raise OSError('sndfile library not found')
  13. OSError: sndfile library not found
  14. # ln -s /export/data/jdder/speech/conda/py27/lib/libsndfile.so.1.0.27 /usr/lib64/libsndfile.so
  15. # python
  16. Python 2.7.13 |Continuum Analytics, Inc.| (default, Dec 20 2016, 23:09:15)
  17. [GCC 4.4.7 20120313 (Red Hat 4.4.7-1)] on linux2
  18. Type "help", "copyright", "credits" or "license" for more information.
  19. Anaconda is brought to you by Continuum Analytics.
  20. Please check out: http://continuum.io/thanks and https://anaconda.org
  21. >>> import soundfile