介绍嵌入式Linux 环境下的动态库、静态库、以及如何在编译时使用动态库和静态库。
1 命名规则
1)动态库格式为libxxx.so, 以lib打头,.so表示动态库,xxx为具体的库名称
2)静态库格式为libxxx.a, 以lib打头,.a表示静态库,xxx为具体的库名称
2 动态库与静态库的区别
1) 编译过程
- 动态库在程序编译链接时仅引用函数接口,编译出来的程序比较小;
- 静态库在程序编译链接时,所用的函数都已经合到程序里,编译出来的程序比较大。
2)板子上部署
- 动态库,因为执行到相关函数才会调用库中相应函数,所以在板子上部署时,需要将动态库放到板子的lib目录下,否则在程序执行时会提示”无法找到xxx动态库”而终止运行程序;
- 静态库,因为在编译链接时已经将所用的函数都加载到可执行程序中,所以不需要再在板子上部署。
3)库更新对程序的影响
- 动态库需要更新时只要使用的函数接口不变,使用它的程序就不需要再次编译,但是需要将更新过的动态库再次部署到板子(替换掉原有的库);
- 静态库有更新时,使用它的程序就需要重新编译。
3 库在程序编译过程的使用方法
程序中不管使用动态还是静态库, 使用方法一样。需要在编译时指定库函数头文件路径,链接时指定库所在路径及库名。
1)用-l指明需要链接的库名称(注l是小写的L)
2)用-L指定库所在的路径
3)用-I包含头文件所在路径(注I是include的首字母大写I)
4 示例
以ssh静态库为例,介绍库在程序编译过程的使用(动态库在编译过程中使用方法相同)。假设程序要使用libssh.a这个静态库,这个库放在与makefile同一级目录的ssh目录中,根据命名规则,该库名称为ssh,在makefile要指定库名、库接口函数所在路径、以及库头文件所在路径。部分makefile如下
LIB = -lssh
LDFLAGS = -L./ssh/lib/
INCLUDE = -I./ssh/include
(OBJS)
@ @ ^ (CFLAG) (LIB)
%.o:%.c
(CFLAG) @ $<
注意,实际我们编译库的时候,特别是编译开源库的时候,编译出来的库有不同的版本,比如libssh.so.4.8.1,那么在实际使用时,要将libssh.so链接到libssh.so.4.8.1后再使用。改成libssh.so,是因为可以用-lssh指明库名,使用起来方便。若坚持要用libssh.so.4.8.1这种命名也可以,在链接时直接指明库就可以了,比如-L./ssh/lib/libssh.so.4.8.1, 这样就不需要再用-lssh指明库了(也无法用这个方式指明,因为这个库已经不叫ssh了)。对于libssh.so这样格式的库名,如果不用-lssh来指明,也可以直接用-L./ssh/lib/libssh.so指明要引用的库。
————————————————
注:本文由同一作者首发于CSDN。