Linux的静态库和动态库
编写库
如果有很多的函数要连接,这些函数可能来自不同的源文件,而且这些函数对于将来要编写的程序可能有用,那么可以直接创建一个库(就是一个存档文件)。库文件分为两种:当编译调用静态库中函数的代码时,那些函数编程最终可执行文件的一部分,另一方面,如果库是动态的,那么直到实际执行了程序,这些函数才会真正附加到调用代码上。
创建静态库
1 | $gcc –g –c a.c |
这样就可以创建一个库文件liba.a,编译主程序时:
1 | $gcc –g main.c –la |
其中-la即为liba.a的缩写,两者含义相同。如果该库文件与源码不在一个目录,比如在lib目录,则需要L选项,即-Llib就可以将lib文件夹添加到搜索库文件的环境变量中。
这种方法的缺点就是如果很多程序使用同一个库,那么每个程序都会在磁盘上包含该库的独立副本,这样比较浪费空间。可以使用动态库解决这个问题(代价是需要一点额外的加载时间)。
创建动态链接库
1 | $gcc –fPIC –c a.c |
这段代码创建了动态库liba.so,(Unix中命名动态库的惯例是使用后缀so,表示shared object,后面可能会跟着版本号。)与连接静态库一样地连接到这个动态库。(其中选项fpic:产生位置无关码
解释一下,位置无关码就是可以在进程的任意内存位置执行的目标码,动态链接库必须使用。)
1 | $gcc –g main.c –la |
开源软件中库的用法
开源软件现在很流行,尤其是在Linux用户之间。然而有时会出现一个问题,即与源代码配套的构建脚本(通常称为配置文件)找不到某些必须的库。试图通过设置LD_LIBRARY_PATH环境变量可能会失败。
这种问题的根源常常在于配置文件调用的名为pkgconfig的程序,这个程序会从某些元数据文件处接收库的信息,这样的文件爱你后缀为.pc,前缀是库的名称,例如,文件爱你libabc.pc中包含库文件libabc.so*的位置。
curses库
这个库简单到很多人根本没有把它当成GUI。
程序员可以使用curses库编写让光标在屏幕上移动的代码,改变字符的颜色,或者改成反白显示,插入以及删除文本等。
例如,像Vim和Emacs这样的文本编辑器就是用curses编写的。
通过直接添加或者手动编译添加库,解决 library not found for -lxxx 等的问题
本文基本上能完美解决这种库文件无法找到问题,一般保存为library not found for -llxxx。
这个问题是说链接器在链接的时候找不到 Ixxx 这个库,那我们就告诉它(添加库的路径),让它找到就好啦!
扩展:
- 静态库无法链接报错:
1 | library not found for -lxxx |
- 动态库无法装载报错:
1 | dyld: library not loaded …/libxxx.dylib |
解决办法
方法一:直接添加库
通常解决办法是:库存在,直接添加路径。
也就是通常遇到这个问题的时候,库是已经编译安装好了的,但是 IED 不能找到。这样的话就直接添加库的路径就好了。
第一步:找库
第一步,自己找到这个库。
库一般放在系统默认处或者安装到特定地方。
Linux 系统默认库放在:
1 | /lib |
1 | /usr/local/Cellar/ice/3.7.0/lib |
第二步:添加路径
添加库一般以下三种方法任选其一:
系统环境变量添加
系统级:修改
/etc/profile
或者/etc/bashrc
用户级:修改
~/.bashrc
或者~/.bash_profile
1 | ###添加库的bin文件夹路径 |
IED 编译环境添加
因 IDE 不同而不同,如 Qt 在
项目
-构建设置
-构建环境
处添加代码添加
1 | # 如 Qt pro 文件添加 |
这样,IDE就能找到库啦!