动态库和静态库

参考资料

参考 gcc创建和使用静态库、动态库
参考 工程下载


工程目录

img


动态库的制作

//创建库并链接库
gcc hello.c -I../include -fPIC -shared -o libhello.so
gcc main.c -I../include -L../lib -lhello -o main -Wl,-rpath=../lib/
gcc 手册 中对于 -shared 的解释
-shared
  	Produce a shared object which can then be linked with other objects to form an executable.  Not all systems support this option.  For predictable results, you must also specify the same set of options used for compilation (-fpic, -fPIC, or model suboptions) when you specify this linker option.[1]

命令解析:
hello.c 源文件
-I../include 头文件所在目录
-fPIC -shared 编译成.so文件所必须的
-o libhello.so 生成目标文件

-lhello 在-L所指定的目录中,链接libhello.so或者libhello.a,先找.so,找不到找.a.都没有连接不会报错,运行报错
-Wl,-rpath=../lib/ 指定运行时寻找动态库的路径

静态库的制作

//创建库并链接库
gcc -c -I../include hello.c
ar rcs libhello.a hello.o
gcc main.c -I../include -L../lib -lhello -o main
命令解析:
ar是gcc套件中的一个工具,用于将多个.o文件打包成.a静态库文件

r
如果.o文件之前不存在库中,则插入
如果.o文件存在库中,则替换
新的.o文件(模块)在库的末尾
c
不管库是否存在,都创建库文件(.a文件)
s
创建目标文件索引,这在创建较大的库时能加快时间

库的使用-编译 包含静态库和动态库

直接一个 -l 就可以了,并指明库的路径.如果有头文件的话,记得要指明头文件路径,
gcc main.c -I../include -L../lib -lhello -o main
1/先找动态库,如果找到,并连接//会运行出错,因为没有指定运行时连接路径
2/动态库找不到,找静态库,并连接到目标//运行正常
  • -shared -static
//-shared 是用来生成动态库的,不是用来链接动态库的
//-static 是用来链接静态库的,不是用来生成静态库的
  • 如果你想在一次连接命令中同时链接动态库和静态库
//动态库
-Wl,-Bdynamic 
选项后面的链接动态库,直到-Wl,-Bstatic

//静态库
-Wl,-Bstatic
选项后面的链接静态库,直到-Wl,-Bdynamic 
  • 在上述过程中,我将main.c的编译和连接放到了一块,你也可以酱紫
//静态库
gcc -c  main.c -I../include  -o main.o
gcc main.o -static -lhello -L../lib/ -o main 
//动态库
gcc -c  main.c -I../include  -o main.o
gcc main.o -L../lib -lhello -o main -Wl,-rpath=../lib/

动态库的使用-运行

静态库没有使用问题,而静态库会有运行时链接问题.
  • 运行时链接

  //默认寻找库,正确,但是运行出错
hunda@hunda-Veriton-X275 ~/tmp/libtest/src $ gcc main.c -I../include -L../lib -lhello -o main
hunda@hunda-Veriton-X275 ~/tmp/libtest/src $ ./main 
./main: error while loading shared libraries: libhello.so: cannot open shared object file: No such file or directory
  //默认寻找库(动态),并指明运行连接路径
hunda@hunda-Veriton-X275 ~/tmp/libtest/src $ gcc main.c -I../include -L../lib -lhello -o main -Wl,-rpath=../lib/
hunda@hunda-Veriton-X275 ~/tmp/libtest/src $ ./main 
dongtai
  • 如果链接的动态库不在标准目录,也就是不在 /lib ,也不再 /usr/lib/ ,而是在另外的目录的话.
可以酱紫,

	1. export LD_LIBRARY_PATH="../lib"
	2. 链接动态库,生成可执行文件
	3. 执行

也可以酱紫(下面的这个是一个选项,指定执行运行时路径)

	1. 连接时加一个-Wl,-rpath=../lib/                 
	2. 执行

动态库在运行时的搜索路径搜索的先后顺序

1. 编译目标代码时指定的动态库搜索路径
2. 环境变量 LD_LIBRARY_PATH 指定的动态库搜索路径
3. 配置文件 /etc/ld.so.conf 中指定的动态库搜索路径
4. 默认的动态库搜索路径 /lib 
5. 默认的动态库搜索路径 /usr/lib

##优劣

  • 静态库:
	1.链接静态库的可执行程序可以在没有库文件支持的系统上运行
	2.文件size大,所以文件大导致的问题,它都有
	3.更新程序要重新链接,麻烦
  • 动态库:
	1.不可以在没有库支持的系统上运行
	2.size小
	3.更新程序不需要重新链接	,简单	

##其他:

  • 可以用ldd来查看一个可执行二进制文件链接了哪些动态库,不能查询链接了哪些静态库

test2.c 依赖 test1.c

gcc test1.c  -fPIC -shared -o libtest1.so //并将libtest1.so 放到标准目录下

gcc test2.c  -fPIC -shared -o libtest2.so

gcc main.c  -L. -ltest2 -ltest1 -o main -Wl,-rpath=.

gcc main.c  -L. -ltest2 -o main -Wl,-rpath=. //这个命令会失败,说找不到 test1.c 中的函数(被test2.c依赖)

gcc test2.c  -fPIC -shared -o libtest2.so -ltest1

gcc main.c  -L. -ltest2 -o main -Wl,-rpath=.//此时成功

最主要的点是 
gcc test2.c  -fPIC -shared -o libtest2.so -ltest1

链接的时候 修复了 依赖关系
  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值