静态库
链接时将代码段直接加载进可执行文件中,运行时就不需要静态库文件,因为静态库中的代码已经在可执行文件中了。
在linux中以 .a 作为静态库文件后缀,Windows中是 .lib
如何制造
[root@localhost linux]# ls
add.c add.h main.c sub.c sub.h
[root@localhost linux]# gcc -c add.c -o add.o
[root@localhost linux]# gcc -c sub.c -o sub.o
生成静态库
[root@localhost linux]# ar -rc libmymath.a add.o sub.o
//库名规则:libxxx.a
动态库
程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。
在linux中以 .so 为后缀(shared objector).
如何制造
[root@localhost linux]# gcc -fPIC -c sub.c add.c
[root@localhost linux]# gcc -shared -o libmymath.so *.o
// -fPIC表示与位置无关码,因为动态库加载进进程中,往往是记录相关函数的偏移量
// -shared表示生成的是一个动态库文件
// 库名规则: libxxx.so
库的链接
我们要使用库,需要编译器和进程(运行时)找到库文件
编译
对于c语言自带的库文件,由于它们都在系统的指定目录下,且编译器都认识它们,因此我们不用做过多的处理,但我们自己的库文件就需要做特殊的处理了
.
├── a.out
├── head
│ └── add.h //头文件
├── lib
│ └── libmymath.so //库文件
└── main.c
gcc main.c -I ./head/ -L./lib/ -lmymath
//-I xxxx 指头文件的路径。
//我们也可以直接在代码中用#include "./head/add.h"来指定头文件位置
//这种情况下就不用-I ./head/了
//-L./lib/ 这是库文件的位置,编译器会按照一套规则去查找库文件。稍后说
//-lmymath这是说明库的名字是mymath,这一步十分重要,因为第三方库不同于c语言默认库
//编译器不认识第三方库,即使告诉编译库的目录,只要不告诉编译器库的名字,编译也不会
//去所期望的库里,因此只有带上名字,编译才会去指定的库里找
查找动态库规则
从左到右搜索-L指定的目录。
由环境变量指定的目录 (LIBRARY_PATH)
//因此可以在环境变量中添加动态库的路径
//export PATH=$PATH:xxxxxx
//但这个环境变量是当前进程,所以重新启动系统,就会失效
//因此可以修改~/.bashrc或者~/.bash_profile或者/etc/profile文件,因为进程的环境变量每次都是从这里加载的
由系统指定的目录
/usr/lib
/usr/local/lib
//可以把库文件直接放在系统指定目录下,或者建立软链接,但不推荐
运行
如果是静态库,那就已经结束了
但动态库在此时会报错
./a.out: error while loading shared libraries: libmymath.so: cannot open shared object file: No such file or directory
因为系统不知道你的动态库在哪里
运行动态库
1、拷贝.so文件到系统共享库路径下, 一般指/usr/lib
2、更改 LD_LIBRARY_PATH
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:xxxxx(不是永久)
修改~/.bashrc或者~/.bash_profile或者/etc/profile文件(永久)
3.ldconfig 配置/etc/ld.so.conf.d/ 用ldconfig更新
/etc/ld.so.conf.d/添加新的文件,文件中记录动态库的路径
再用ldconfig指令更新