静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
动态库
优点
节省磁盘空间,且多个用到相同动态库的程序同时运行时,库文件会通过进程地址空间进行共享,内存当中不会存在重复代码。
缺点
必须依赖动态库,否则无法运行。
静态库
优点
使用静态库生成可执行程序后,该可执行程序就可以独自运行,不再需要库了。
缺点
使用静态库生成可执行程序会占用大量空间,特别是当有多个静态程序同时加载而这些静态程序使用的都是相同的库,这时在内存当中就会存在大量的重复代码。
add.h
int Add(int a,int b);
add.c:
#include"add.h"
int Add(int a,int b)
{
return a+b;
}
sub.h
int Sub(int a,int b);
sub.c
#include "sub.h"
int Sub(int a,int b)
{
return a-b;
}
第一步
生成.o文件
gcc -c add.c -o add.o
gcc -c sub.c -o sub.o
第二步
执行指令
ar -rc libmymath.a add.o sub.o
ar是gnu归档工具,rc表示(replace and create)
这样就生成了静态库
第三步
将头文件和生成的静态库组织起来
mkdir -p lib-static/lib
mkdir -p lib-static/include
cp *.a lib-static/lib
cp *.h lib-static/include
第一步
利用-fPIC选项生成.o文件
gcc -fPIC -c add.c -o add.o
gcc -fPIC -c sub.c -o sub.o
第二步
使用-shared选项将所有目标文件打包为动态库
gcc -shared -o libmymath.so mymath.o myprint.o
第三步
将头文件和生成的动态库组织起来
mkdir -p lib-dyna/lib
mkdir -p lib-dyna/include
cp *.a lib-dyna/lib
cp *.h lib-dyna/include
方法一:
直接指定静态库的路径
gcc test.c -o test -I../lib-static/include -L../lib-static/lib -lmymath
-I:指定头文件搜索路径。
-L:指定库文件搜索路径。
-l:指明需要链接库文件路径下的哪一个库。
方法二
把头文件和库文件拷贝到系统路径下
不推荐,会污染系统文件
sudo cp lib-static/include/* /usr/include/ sudo cp
lib-static/lib/libmymath.a /lib64/
但当我们使用gcc编译test.c生成可执行程序时,只需要指明需要链接库文件路径下的哪一个库
我们可以和之前一样按照前面的方法生成可执行程序
gcc test.c -o test -I../lib-dyna/include -L../lib-dyna/lib -lmymath
但是我们会面临这个问题
如何解决的这个问题呢?
方法一
拷贝.so文件到系统共享库路径下, 一般指/usr/lib(不推荐,这里就不做演示了)
方法二
更改 LD_LIBRARY_PATH,增加.so文件的路径
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/home/zjq/linuxl/10-28/lib/lib-dyna/lib
这样就可以执行了
但这样有一个问题,当重启机器后,环境变量未配置到系统文件中,会删除刚刚配置的环境变量
方法三
ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新(推荐)
在/etc/ld.so.conf.d/路径下,添加新文件,写入动态库的路径即可
touch /etc/ld.so.conf.d/mymath.conf
ldconfig更新该路径即可
ldconfig