静态库
静态库在某种程度上可以看作是一堆 .o(目标文件)的集合。静态库中的代码链接时会被直接嵌入到最终的可执行文件中。
特点
占用磁盘空间大
运行速度快
库更新后需要,程序重新编译链接
创建
- 编译产生 .o 文件
gcc -c xxx.c
这里的 xxx.c 就是编写的代码文件
- 使用ar工具创建静态库 .a 文件
ar -rsv libxxx.a xxx.o
这里的 libxxx.a 是生成的静态库文件名,必须以 lib 开头,后缀为 .a (也就是说静态库名称是xxx)
xxx.o 是之前编译产生的文件
-rsv可以替换成其他参数,详情查阅其他资料
两个 xxx 不一定相同,自己取名
例如:ar -rsv libmya.a a1.o a2.o a3.o
- 链接静态库
gcc -o xxx xxx.c -L. -lxxx
前半部分是常规编译汇编链接过程,重点在 -L. 和 -lxxx
-L. 代表链接的当前路径,这个 . 就是当前目录,可以更换
-lxxx 的 xxx 是静态库名称
例如:gcc -o test a1.c a2.c a3.c -L. -lmya
动态库
动态库也叫共享库,动态库在程序编译时并不会被链接到目标代码中,不同的应用程序可以共享同一个动态库。
特点
占用空间小(不含库中代码)
多程序共享库
库更新方便,不用重新编译程序,易于移植、部署
创建
- 编译产生 .o 文件
gcc -c -fPIC xxx.c
一定要有 -fPIC
这个参数,这是创建与地址无关的编译程序,是为了能够在多个应用程序间共享
- 生成动态库 .so 文件
gcc -shared -o libxxx.so xxx.o
生成动态库不需要多余的工具,只需加上 -shared
参数即可
因此,现在可以看出,其实只需要一句命令就能完成这两个过程:
gcc -fPIC -shared -o libxxx.so xxx.o
- 链接动态库
gcc -o xxx xxx.c -L. -lxxx
和静态库方法相同
常见问题
error while loading shared libraries: 1 xxx.so: cannot open shared object file: No such file or directory
动态依赖库不会在当前目录下寻找 .so 文件,而一般会在 /usr/lib 或者 /lib 目录下,因此,把 .so 文件拷贝到那个目录下即可
当然,如果不想目录下被经常拷贝导致混乱,还有如下办法:
export LD_LIBRARY_PATH=xxx
注:xxx 为绝对路径
使用这种方法的话,每次新打开终端都要执行这个命令才有用,因此可以在 bashrc 文件里面进行配置
- vi ~/.bashrc
- 在最后一行添加命令
- source ~/.bashrc