目录
[1 静态库](#1 静态库)
[1.1 静态库概念](#1.1 静态库概念)
[1.2 创建静态库](#1.2 创建静态库)
[1.3 使用静态库](#1.3 使用静态库)
[1.4 库安装](#1.4 库安装)
[2 动态库](#2 动态库)
[2.1 动态库的概念](#2.1 动态库的概念)
[2.2 动态库的创建](#2.2 动态库的创建)
[2.3 动态库的使用](#2.3 动态库的使用)
[2.4 动态库查找](#2.4 动态库查找)
1 静态库
⼀个可执⾏程序可能⽤到许多的库,这些库运⾏有的是静态库,有的是动态库,⽽我们的编译默认为动态链接库 ,只有在该库下找不到动态.so的时候才会采⽤同名静态库。我们也可以使⽤ gcc的 -static 强转设置链接静态库。
1.1 静态库概念
(1)本质
静态库是预编译的目标文件(.o或.obj)的集合,通过归档工具(如ar)打包成一个单独的文件
静态库会合并自己的的代码到可执行程序中,一旦形成就不依赖静态库了,因此是看不到对静态库的依赖
(2)文件扩展名
- Unix/Linux系统: .a (archive)
- Windows系统: .lib
- macOS: .a 或 .framework
(3)查看一个可执行文件的库链接信息
cpp
lz@VM-8-15-ubuntu:~/learn/lib$ ldd a.out
linux-vdso.so.1 (0x00007fffba3fb000)
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007abb0b400000)
/lib64/ld-linux-x86-64.so.2 (0x00007abb0b729000)
cpp
lz@VM-8-15-ubuntu:~/learn/lib$ file a.out
a.out: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=0ce96b945614d129ad904d4be25ef8b6ab6360e1, for GNU/Linux 3.2.0, not stripped
1.2 创建静态库
(1)Linux/Unix下创建静态库
- 编译源文件为目标文件(.o或.obj)
cpp
lz@VM-8-15-ubuntu:~/learn/lib$ g++ -c *.cpp
- 创建静态库
cpp
ar rcs libmylib.a *.o
- r - 替换库中现有文件
- c - 创建库(如果不存在)
- s - 创建索引
- 查看静态库
cpp
ar -t libmylib.a
nm libmylib.a
1.3 使用静态库
(1)链接静态库
库⽂件名称和引⼊库的名称:去掉前缀 lib ,去掉后缀 .so , .a ,如: libc.so -> c
cpp
// 场景1:头⽂件和库⽂件安装到系统路径下(lib或者lib64)
$ gcc main.cpp -lmylib
// 场景2:头⽂件和库⽂件和我们⾃⼰的源⽂件在同⼀个路径下
$ gcc main.c -L. -lmymath
// 场景3:头⽂件和库⽂件有⾃⼰的独⽴路径
$ gcc main.c -I头⽂件路径 -L库⽂件路径 -lmymath
- -L - 指定库搜索路径
- -l - 指定库名(去掉lib前缀和.a后缀)
- -I: 指定头⽂件搜索路径
1.4 库安装
库 = 头文件 + 库文件(代码实现)
(1)库安装
本质是把 头文件 和 库文件 拷贝到系统的默认路径,编译器能找到的路径下
- 编译器指定找头文件路径:/user/include
- 编译器指定找库文件路径:/lib64
2 动态库
2.1 动态库的概念
(1)本质
动态库是包含可被多个程序共享的代码和数据的二进制文件,在程序运行时由动态链接器加载到内存。
(2)文件扩展名
- Unix/Linux系统: .so (Shared Object)
- Windows系统: .dll (Dynamic Link Library)
- macOS: .dylib 或
2.2 动态库的创建
(1)Linux/Unix下创建动态库
- 编译为位置无关代码:
cpp
gcc -fPIC -c file1.c file2.c
- 创建动态库:
cpp
gcc -shared -o libmylib.so file1.o file2.o
- 设置库搜索路径(可选):
cpp
export LD_LIBRARY_PATH=/path/to/libs:$LD_LIBRARY_PATH
- shared: 表⽰⽣成共享库格式
- **fPIC:**产⽣位置⽆关码(position independent code)
- **库名规则:**libxxx.so
2.3 动态库的使用
(1)链接动态库
库⽂件名称和引⼊库的名称:去掉前缀 lib ,去掉后缀 .so , .a ,如: libc.so -> c
cpp
// 场景1:头⽂件和库⽂件安装到系统路径下(lib或者lib64)
$ g++ main.cpp -lmylib
// 场景2:头⽂件和库⽂件和我们⾃⼰的源⽂件在同⼀个路径下
$ g++ -o main main.cpp -L. -lmylib
// 场景3:头⽂件和库⽂件有⾃⼰的独⽴路径
$ g++ -o main main.cpp -I头⽂件路径 -L库⽂件路径 -lmymath
2.4 动态库查找
cpp
$ ldd a.out
linux-vdso.so.1 => (0x00007fff4d396000)
libmystdio.so => not found
libc.so.6 => /lib64/libc.so.6 (0x00007fa2aef30000)
/lib64/ld-linux-x86-64.so.2 (0x00007fa2af2fe000)
- 拷⻉ .so ⽂件到系统共享库路径下, ⼀般指 /usr/lib、/usr/local/lib、/lib64 或者开篇指明的库路径等
- 向系统共享库路径下建⽴同名软连接
- 更改环境变量:LD_LIBRARY_PATH
- 更改系统配置文件:/etc/ld.so.conf.d/
(1)创建新的配置文件,必须以 .conf 结尾
(2)写入动态库的绝对路径
(3) 执⾏ ldconfig ,重新加载库搜索路径