linux库制作
文件目录
- 1. 什么是库
- 2.静态库
- 2.1 静态库的生成
- 2.2 静态库使用
- 3. 动态库
- 3.1 动态库生成
- 3.2 动态库使用
- 3.3 库运行搜索路径
- 3.3.1 问题
- 3.3.2 解决方案
1. 什么是库
库是写好的现有的,成熟的,可以复用的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个人的代码都从零开始,因此库的存在意义非同寻常。
本质上来说库是一种可执行代码的二进制形式,可以被操作系统载入内存执行。库有两种:
- 静态库 .a [Linux]、.lib [windows]
- 动态库 .so [Linux]、.dll [windows]
2.静态库
- 静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中,程序运行的时候将不再需要静态库。
- 一个可执行程序可能用到许多的库,这些库运行有的是静态库,有的是动态库,而我们的编译默认为动态链接库,只有在该库下找不到动态.so的时候才会采用同名静态库。我们也可以使用gcc的-static 强转设置链接静态库。
2.1 静态库的生成
//Makefile 1 libtest.a:test.o mystring.o 2 @ar-rc $@ $^ 3%.o:%.c 4 @gcc-c $< 5 6.PHONY:clean 7 clean: 8rm-rf*.a*.o stdc* 9 10.PHONY:output 11 output: 12 @mkdir-p mylib 13 @mkdir-p mylib/include 14 @mkdir-p mylib/lib 15 @cp-f*.h mylib/include 16 @cp-f*.a mylib/lib- 是gnu 归档工具,rc 表示(replace and create)
[zhangsan@VM-0-17-centos 2026-11-3]$ ar-tv libtest.a rw-rw-r--1003/1003 1496 Nov 3 18:07 2026 test.o rw-rw-r--1003/1003 1520 Nov 3 18:07 2026 mystring.o- t: 列出静态库中的文件
- v :verbose 详细信息
2.2 静态库使用
1//任意目录下新建 2//main.c引入库头文件 3#include "test.h"4#include "mystring.h"5 6 int main()7{8 Print();9 mystring();10return1;11}//场景1:头文件和库文件安装到系统路径下 $ gcc main.c-lmystdio//场景2:头文件和库文件和我们自己的源文件在同一个路径下 $ gcc main.c-L.-lmymath//场景3:头文件和库文件有自己的独立路径 $ gcc main.c-I头文件路径-L库文件路径-lmymath gcc main.c-I mylib/include-L mylib/lib-l test- -L :指定库路径
- -I : 指定头文件搜索路径
- -l :指定库名
- 库文件名称和引入库的名称:去掉前缀lib ,去掉后缀.so ,,如: libc .so -> c
3. 动态库
- 动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
- 一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码
- 在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接(dynamic linking)
- 动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间。
3.1 动态库生成
//Makefile 1 libtest.so:test.o mystring.o 2 gcc-o $@ $^-shared 3%.o:%.c 4 gcc-fPIC-c $< 5 6.PHONY:clean 7 clean: 8rm-rf*.so*.o stdc* 9 10.PHONY:output 11 output: 12 @mkdir-p mylib 13 @mkdir-p mylib/include 14 @mkdir-p mylib/lib 15 @cp-f*.h mylib/include 16 @cp-f*.so mylib/lib- shared:表示生成共享库格式
- fPIC:产生位置无关码(position independent code)
- 库名规则:libxxx.so
3.2 动态库使用
场景1:头文件和库文件安装到系统路径下
$ gcc main .c -lmystdio
场景2:头文件和库文件和我们自己的源文件在同一个路径下
$ gcc main .c -L . -lmymath // 从左到右搜索-L指定的目录
场景3:头文件和库文件有自己的独立路径
$ gcc main .c -I头文件路径-L库文件路径-lmymath
$ ldd libmystdio.so // 查看库或者可执行程序的依赖
linux-vdso .so .1 => (0x00007fffacbbf000)
libc.so.6 => /lib64/libc.so.6 (0x00007f8917335000)
/lib64/ld-linux-x86-64.so.2 (0x00007f8917905000)
3.3 库运行搜索路径
3.3.1 问题
1 2 $ ldd a.out 3 linux-vdso.so.1 =>(0x00007fff4d396000)4 libtest.so => not found 5 libc.so.6 =>/lib64/libc.so.6(0x00007fa2aef30000)6/lib64/ld-linux-x86-64.so.2(0x00007fa2af2fe000)可以看到libtest.so动态库找不到,这是因为动态库我们不仅需要让编译器知道,还需要让操作系统知道
3.3.2 解决方案
- 拷贝.so 文件到系统共享库路径下,一般指/usr/lib、/usr/local/lib、/lib64 或者开篇指明的库路径等
- 向系统共享库路径下建立同名软连接
- 更改环境变量:LD LIBRARY PATH