1. 静态库
现在有两个.h和.c文件,分别是头文件和方法实现
制作库
1. 编译汇编形成.o为后缀的目标文件
gcc -c add.c sub.c
2. 把所有的.o 文件打包形成静态库
ar -rc libname.a *.o
ar 是归档工具(Archive file)r对应replace c对应creat
ar -tv libname.a
列出静态库中的文件的详细信息
3. 把所有头文件放在一个目录下,所有库文件放在一个目录下,然后打包压缩
使用库
有两种方法:
1. 放到系统库中
头文件:/usr/include
库文件:/usr/lib或/usr/lib64
gcc会默认在这些路径下搜索
gcc -o test test.c -l libname
如果不带-l libname 编译器是不认识这个库的,官方提供的库编译器认识
libname是libname.a 去掉前缀lib和后缀.a后的name
2. 给编译器指定路径
gcc -o test test.c -I (头文件路径) -L (库路径) -l libname
-I(大写i)-L -l(小写L)
2. 动态库
制作库
1. 编译汇编形成.o为后缀的目标文件
gcc -fPIC -c add.c sub.c
-fPIC 形成位置无关码,采用相对位置编码,在原理具体说明
2. 打包形成库文件
gcc -shared -o libname.so *.o
使用编译器gcc来打包
使用库
在编译层面,动态库和静态库一样,两种方法
但是程序编译出来后却不能运行
这是因为程序也需要知道动态库在哪里,在执行时才可以调用
针对这个问题,有下面几种方法:
1. 放到系统路径下,和静态库一个道理
2. 在/usr/lib64 路径下建立软链接
3. export修改环境变量LD_LIBRARY_PATH(可在.bash_profile或.bashrc配置文件更改)
4. /etc/ldd.so.conf.d/目录下创建name.conf文件,文件内容为库的路径,再重新blconfig
3. 动静态库编译原理
静态库编译就是把代码拷贝到对应位置,链接起来,地址是连续的,编译后形成程序,不再依赖库就可以运行,把库删除了也可以运行。
这样会让程序的大小变大很多
动态库编译,就不会拷贝这个函数的方法的代码到程序中,而是告诉程序,我这里有方法,你运行的时候再来取。
什么是位置无关码 -fPIC 编码采用相对位置,当gcc编译时,就会以库的起始位置+函数偏移量来标识一个函数
程序运行起来时,动态库如果没有被加载到内存,OS会把动态库加载到内存,并且和虚拟内存通过页表建立映射,如果已经被加载到内存,直接建立映射关系,因为动态库的代码是只读的,所有使用这个动态库的实际上在内存上只有一份代码。
因为是相对位置编码,当代码执行到需要的库函数时,会从代码区跳转到共享区去读动态库的代码,怎么找到的?在编码的时候就是库的起始位置加函数偏移量,库的起始位置在进程执行时,映射时就知道的,而函数的偏移量,是动态库-fPIC 时就有的。
完。