文章目录
- 静态库
- 制作静态库并发布
- 如何使用第三方静态库
- 方式一
- 方式二:
- 方式三
- 动态库
- 制作动态库并发布
- 链接动态库
- 方式一
- 方式二
- 方式三
- 方式四
- 生成共享库参数
- 动静态库总结
静态库
程序在编译链接的时候,直接将该库拷贝一份到源文件,运行的时候不再需要该静态库。
静态库的命名方式:以lib为前缀,以.a为后缀。
制作静态库并发布
1.把函数声明都放在一个或多个.h的头文件里
2.把.h中的声明的函数实现放在.c文件里
3.把这些.c文件生成.o文件
4.把生成的多个.o文件打包放到.a文件里(其实.o文件就可以直接与我们的源文件进行链接形成可执行程序了,但为了方便使用,我们把多个.o文件打包放到了.a文件里)
生成的库名称
声明生成的库名字为libmymath.a
#形成的库名字叫做libmymath.a
lib=libmymath.a
将.c文件生成.o文件
# gcc命令只加$^ 默认把.c文件形成与$@同名的.o文件
div.o add.o:div.c add.c
gcc -c $^
将.o文件打包放到静态库.a文件里
#ar是生成静态库的命令 生成的库依赖的是.o文件
$(lib):div.o add.o
ar -rc $@ $^
ar命令是打包命令,意为将$ ^文件都放到$ @文件里,
这里的$ ^文件为div.o和add.o,$@文件为库文件libmymath.a
发布
就是创建一个目录,用来存放头文件目录include和库文件目录,分别用来放头文件.h和库文件.a(.a文件里放的是.o文件集合)
.PHONY:output
output:
mkdir -p lib/include
mkdir -p lib/mymathlib
cp *.h lib/include
cp *.a lib/mymathlib
清除
.PHONY:clean
clean:
rm -rf *.a *.o lib
静态库可不可以不包含头文件呢?
不可以,因为头文件是这个库文件所提供的方法的说明书,你不提供,使用者就不知道这个文件里有哪些方法,怎么去调用
lib目录里面放的是库的集合
Makefile文件
#形成的库名字叫做libmymath.a
lib=libmymath.a
#ar是生成静态库的命令 生成的库依赖的是.o文件
$(lib):add.o div.o
ar -rc $@ $^
# gcc命令只加$^ 默认把.c文件形成与$@同名的.o文件
div.o add.o:div.c add.c
gcc -c $^
.PHONY:clean
clean:
rm -rf *.a *.o lib
.PHONY:output
output:
mkdir -p lib/include
mkdir -p lib/mymathlib
cp *.h lib/include
cp *.a lib/mymathlib
通过为 gcc 指令添加 -c 选项(注意是小写字母 c),即可让 GCC 编译器将指定文件加工至汇编阶段,并生成相应的目标.o文件
如何使用第三方静态库
方式一
直接将已发布的第三方静态库拷贝到当前目录下
1.先把库集合lib目录文件拷贝到当前目录下,不拷贝也行只要你能找到
2.生成可执行程序
生成可执行程序要指明要链接的库的路径和头文件,
大I选项:用于指明头文件路径
-I ./lib/include/
大L选项:用于指明要链接的库,需要在哪个路径下去搜索
-L ./lib/mymathlib/
小l选项:用于指明要链接哪一个库
这里的库名是libmymath.a,但库的真实名字是去掉前缀去掉后缀,留下来的才是真实的名字
一般建议小l后面紧跟真实的名字
-lmymath
1.为什么头文件指明搜索路径就可以了?不需要再指明具体是哪一个.h头文件呢?
因为在.c源文件中我们已经指明了要包含哪一个头文件,例如这里的#include “add.h”
2.源文件默认只会在当前路径下进行搜索或者默认的库路径下去搜索,当前路径是指在同一级别,main.c和lib是在同一目录下,但是和lib下的文件,就不属于同一目录级别的了,系统默认不会去搜索,因此需要我们手动的带选项去指明要去搜索的路径,且要指明要链接该路径下的哪一个文件。
-L 指定库路径
-l 指定库名
测试目标文件生成后,静态库删掉,程序照样可以运行
方式二:
将第三方库拷贝到默认库路径下
头文件:
拷贝到系统库文件/usr/include/下
库文件:
拷贝到系统文件/lib64/路径下
注意即使拷贝到系统默认路径下了,也要指明要链接的库名称
方式三
建立软链接,链接到系统路径下
这里要求把路径带全
在生成可执行程序时,要指明要链接的库的名称
动态库
制作动态库并发布
动态库的生成和发布与静态库,基本没有什么相同
不同的是:
1.动态库我们也以lib开头但以.so为后缀,与静态库进行区分。
2.生成的库为共享库
shared: 表示生成共享库格式
fPIC:产生位置无关码(position independent code)
库名规则:libxxx.so
3.编译阶段使用动态库
编译选项
l:链接动态库,只要库名即可(去掉lib以及版本号)
L:链接库所在的路径.
库名为libmymethod.so
生成可执行程序示例: gcc main.c –L… -I… -lmethod
4.链接动态库方式有所不同
1、拷贝.so文件到系统共享库路径下, 一般指/usr/lib64
2.在系统默认的库路径下建立软链接 /usr/lib64
3、将自己的库所在的路径,添加到系统的环境变量 LD_LIBRARY_PATH中
4、ldconfig 配置/etc/ld.so.conf.d/,ldconfig更新
链接动态库
方式一
拷贝.so文件到系统共享库路径下, 一般指/usr/lib64
方式二
在系统默认的库路径下建立软链接 /usr/lib64
方式三
将自己的库所在的路径,添加到系统的环境变量 LD_LIBRARY_PATH中
方式四
/etc/ld.so.conf.d/下建立自己的动态库路径的配置文件,然后重新ldconfig(这是更新配置文件命令)即可
生成共享库参数
shared: 表示生成共享库格式
fPIC:产生位置无关码(position independent code)
库名规则:libxxx.so
我们来了解一下产生位置无关码的fPIC是什么
动静态库总结
动静态库其实在使用上基本类似,不同点是
静态库(.a):程序在编译链接的时候把库的代码链接到可执行文件中。程序运行的时候将不再需要静态库
动态库(.so):程序在运行的时候才去链接动态库的代码,多个程序共享使用库的代码。