gcc生成静态库、动态库
0. 静态库.a和动态库.so的区别:
静态库的代码在编译过程中已经被载入可执行程序,因此体积比较大。
动态库(共享库)的代码在可执行程序运行时才载入内存,在编译过程中仅简单的引用,因此代码体积比较小。
1. 生成静态库:
假设有这样一个cpp程序hello.c
#include "hello.h"
void sayhello()
{
printf("hello,world ");
}
- 生成目标文件hello.o:
gcc -o hello.o -c hello.c
- 使用ar(archive)将hello.o打包成libhello.a静态库
ar -rc libhello.a hello.o
解释一下ar后带的参数:
?? -r :表示将.o文件插入到.a中
?? -c : 表示创建一个静态库文件
?? -d : 表示删除这个静态库文件
?? -t : 表示列出.a文件中所有成员
- 编译main.c文件并链接libhello.a
gcc -o app_static -c main.c libhello.a
2. 生成动态库:
- 生成目标文件hello.o:
gcc -fPIC -o hello.o -c hello.c //-fPIC 表示编译为位置独立(地址无关)的代码,不用此选项的话,编译后的代码是位置相关的,所以动态载入时,是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
- 生成动态库文件hello.so
gcc -shared -o hello.so hello.o //-shared 指定生成动态连接库
1和2可以连在一起写:
ar -shared -fPIC -o hello.so hello.c
- 编译main.c文件并链接libhello.so
gcc -o app_shared main.c -L. -lhello
//或者直接写出动态库路径
gcc -o main main.c ./libhello.so
解释一下动态库链接时后的参数:
?? -L : 指定编译器在搜索动态库时搜索的路径,"."意思是当前路径
?? -l (小写l) :一般加库文件名,即hello,如果在—L的路径下找不到,就去LD_LIBRARY_PATH等环境变量的路径下去查找
?? -I (大写i) : 指定路径为首要路径进去搜索头文件,-I/home/include/
就表示搜索头文件从:/home/include/
--> /usr/include --> /usr/local/include
- 提一嘴:修改linux下动态库的环境变量: LIBRARY_PATH与LD_LIBPARY_PATH
LIBRARY_PATH:gcc编译时查找动态库的指定存放路径
LD_LIBPARY_PATH:程序运行加载时要查找动态库的指定存放路径
export LIBRARY_PATH=/home/other/test/lib:$LIBRARY_PATH
export LD_LIBPARY_PATH=/home/other/test/lib:$LD_LIBPARY_PATH
如果不希望退出终端,这个添加路径就失效,永久添加方法:
修改 ~/.bashrc或者系统下的/etc/profile
添加例如export LD_LIBRARY_PATH=/home/other/test/lib:$LD_LIBRARY_PATH
保存,./bashrc