linux下静态库动态库的编译及使用
linux下静态库动态库的编译及使用
为什么要使用库
库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。
库的使用可以使程序模块化。
以C++为例子,库分为静态库和动态库,所谓的静态和动态指的是库链接的方式。
- 静态库(.a、.lib):顾名思义就是在程序的链接阶段被复制到了程序中,和程序运行的时候没有关系。在linux下以.a为后缀,在win下面以.lib为后缀。
- 动态库(.so、.dll):动态库就是在链接阶段没有被复制到程序中,而是程序在运行时由系统动态加载到内存中供程序调用。在linux下以.so为后缀,在win下面以.dll为后缀。

如何使用静态库
以linux 下使用举例:
Linux通常把库文件存放在/usr/lib或/lib目录下。
静态库的创建和使用:
- 在一个头文件种声明静态库所导出的函数。
- 在一个源文件种实现静态库所导出的函数。
- 编译源文件,生成可执行代码。
- 将可执行代码所在的目标文件加入到某个静态库中,为了方便调用,不修改环境变量,可将静态库拷贝到系统默认的存放库文件的目录下。
下面通过一个例子来说明:
- mylib.h:存放的是静态库提供给用户使用的函数的声明
- mylib.c:实现了mylib.h种声明的函数
头文件:mylib.h
1 |
|
源文件:mylib.c
1 |
|
静态库编译步骤
- 编译mylib.c生成目标文件:
gcc -o mylib.o -c mylib.c

- 将目标文件加入到静态库中:
ar rcs libmylib.a mylib.o

- 将静态库copy到Linux的库目录(/usr/lib或者/lib)下(此举是为了不修改环境变量,方便测试链接):
cp libmylib.a /usr/lib/libmylib.a
静态库的链接
- 编写调用库函数的测试程序test.c
1 |
|
- 使用静态库编译:gcc -o test test.c -lmylib
这里注意,编译时无需带上前缀和后缀。
如果没有执行上个的3步骤,没有将静态库拷贝到/usr/lib,而是。
则可以使用以下命令:
1 | gcc -o test test.c -lmylib -L ./ |

- 运行可执行程序
1 | ./test |

静态库编译说明
在Linxu下,可以使用ar命令来创建和修改静态库。
这些在linux下man ar 一下就可以得到参数,这里说明几个常用的:
- d:从库中删除成员文件
- r:在库中加入成员文件,若存在,则替换
- c:创建一个库
- s:无论ar命令是否修改了库内容,都强制重新生成库符号表
其他的命令用时再man。
- -L:表示要连接的库所在目录
- -l:指定链接时需要的动态库,编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.a或.so来确定库的名称。
如何使用动态库
依旧以linux 下使用举例:
依旧用上述的三个文件,mylib.c,mylib.h,test.c来做例子。
动态库的编译
- 编译mylib.c生成目标文件(-fPIC):
gcc -fPIC -o mylib.o -c mylib.c

- 将目标文件加入到动态库中:
gcc -shared -o libmylib.so mylib.o

- 将动态库copy到Linux的库目录(/usr/lib或者/lib)下(此举是为了不修改环境变量,方便测试链接):
cp libmylib.so /usr/lib/libmylib.so
当然1,2两个步骤可以合二为一:
gcc -fPIC -shared -o libmylib.so mylib.c
切记:不要写成 gcc -fPIC -shared -o libmylib.so -c mylib.c
在c文件后面不要加上-c。不然在执行可执行文件的时候会出现以下错误:
./Test: error while loading shared libraries: /lib/libmylib.so: only ET_DYN and ET_EXEC can be loaded
动态库的链接
- 依旧采用上述的test.c
- 使用动态链接库编译可执行程序
gcc -o Test test.c -lmylib -L./
- 运行可执行程序: ./Test
注意这里会有错误:
./Test: error while loading shared libraries: libmylib.so: cannot open shared object file: No such file or directory
是因为,当前的目录不在linux检索的动态库目录范围内。
修改方法:
- 通过修改动态库链接路径:
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/test/so_lib - 直接把库拷贝进入系统默认的路径:/usr/lib/或者/lib/,执行ldconfig。
LD_LIBRARY_PATH: 动态库的查找路径方式
修改当前的动态库路径
- 方法一:export LD_LIBRARY_PATH=LD_LIBRARY_PATH:/XXX 但是登出后就失效
- 方法二:修改./bash_profile或系统级别的/etc/profile
- 在其中添加例如export PATH=/opt/ActiveP/lib:$LD_LIBRARY_PATH
- source .bashrc (Source命令也称为“点命令”,也就是一个点符号.)
- source命令通常用于重新执行刚修改的初始化文件,使之立即生效,而不必注销并重新登录)
- 方法三:这个没有修改LD_LIBRARY_PATH但是效果是一样的实现动态库的查找




