动静态库的制作和使用
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静
态库
动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
一个与动态库链接的可执行文件仅仅包含它用到的函数入口地址的一个表,而不是外部函数所在目标文件的整个机器码
在可执行文件开始运行以前,外部函数的机器码由操作系统从磁盘上的该动态库中复制到内存中,这个过程称为动态链接
动态库可以在多个程序间共享,所以动态链接使得可执行文件更小,节省了磁盘空间。操作系统采用虚拟内存机制允许物理内存中的一份动态库被要用到该库的所有进程共用,节省了内存和磁盘空间
静态库
1.静态库的制作
这里假设有四个文件分别是
myadd.c
myadd.h
myprint.c
myprint.h
我们要把它们打包成静态库给main.c使用
这里可以通过gcc的-c选项把文件编译到目标文件.o阶段
gcc -c myadd.c -o myadd.o
gcc -c myprint.c -o myprint.o
再通过ar的-rc选项把两个目标文件打包成静态库
再把生成的.a静态库和头文件分类放在同一个文件夹内,这个文件夹称为静态库
可以通过makefile自动化完成以上操作:
libhello.a:myadd.o myprint.o
ar -rc libhello.a myadd.o myprint.o
myadd.o:myadd.c
gcc -c myadd.c -o myadd.o
myprint.o:myprint.c
gcc -c myprint.c -o myprint.o
.PHONY:hello
hello:
mkdir -p hello/lib
mkdir -p hello/include
cp -rf *.a hello/lib
cp -rf *.h hello/include
.PHONY:clean
clean:
rm -f libhello.a *.o hello
2.静态库的使用
方法1:
把静态库内的文件拷贝到系统默认搜索路径(需要sudo或者root权限)
把.h文件拷贝到/lib64目录
把.a文件拷贝到/usr/include/目录
cp hello/include/* /usr/include-rf
cp jello/lib/libhello.a /lib64 -rf
然后就可以不指定路径直接调用库了
gcc main.c -l hello
方法2:
指定gcc的搜索路径
-I选项后接.h文件所在目录,-L选项后接库目录,-l选项后接库目录内指定的静态库
注意这里指定的库要去掉头和尾(lib/.a)
gcc main.c -I./hello/include -L./hello/lib -l./hello
动态库
1.动态库的制作
首先和静态库一样,我们先要有四个文件
myadd.c
myadd.h
myprint.c
myprint.h
把它们编译到目标文件.o阶段后打包成动态库(这里注意选项和静态库不同)
gcc -c -fPIC myadd.c -o myadd.o
gcc -c -fPIC myprint.c -o myprint.o
gcc -shared -o libhello.so myadd.o myprint.o
再把生成的.so动态库和头文件分类放在同一个文件夹内,这个文件夹称为动态库
可以通过makefile自动化完成以上操作:
libhello.so:myadd.o myprint.o
gcc -shared -o libhello.so myadd.o myprint.o
myadd.o:myadd.c
gcc -c -fPIC myadd.c -o myadd.o
myprint.o:myprint.c
gcc -c -fPIC myprint.c -o myprint.o
.PHONY:hello
hello:
mkdir -p hello/lib
mkdir -p hello/include
cp -rf *.so hello/lib
cp -rf *.h hello/include
.PHONY:clean
clean:
rm -f libhello.so *.o hello
2.动态库的使用
首先我们用gcc命令指定头文件和库路径后生成可执行程序
gcc main.c -I hello/include -L hello/lib -l hello
然后我们执行这个可执行程序的时候会报错,提示我们库,原因是我们上面的路径是指定给gcc的,当可执行程序需要链接动态库时要告诉系统库在哪里
怎么告诉告诉系统库在哪里呢?
这里提供了四种方法,选择其一即可
1.和静态库一样,可以选择把动态库放入系统路径下
2.修改环境变量(只在本次登录有效)
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:+库所在的绝对路径
3.修改配置文件(永久有效)
touch /etc/ld.so.conf.d/myconf.conf
vim /etc/ld.so.conf.d/myconf.conf
记得修改完配置文件后要用ldconfig刷新哦!
4.把库的路径软连接到保存库的系统路径下
ln -s +库的绝对路径 /lib64/lib库名.so
注意:修改配置文件和ldconfig需要root权限或者sudo命令
写在后面:
当lib文件夹中有同名的动态库和静态库时,gcc会优先链接动态库
也可以通过 gcc后接-static命令强制链接静态库