一篇blog带你深入动静态库~

19 篇文章 0 订阅

序言

创建软链接和硬链接

在这里插入图片描述

不能为目录创建硬链接
在这里插入图片描述

为什么会这样?

在linux中,对于每一个目录文件最终都有指向根目录的指针,如果硬链接指向一个目录,那么最终有可能形成环形路径
软链接是一个链接文件,硬链接是一个普通文件,这也说明硬链接文件如果是目录文件,那么这个文件可能在中途被当做普通文件使用
这也会导致不可避免的事发生,所以系统也不允许建立硬链接
在这里插入图片描述

而对于这个. 和…这两个文件就是系统规定的两个硬链接(唯一的两个)
ACM时间:

access 最后访问时间
modifiy 文件最后修改时间
change 属性最后修改时间

静态库

在文件编译链接时,把库的代码连接到可执行文件中,程序运行不再需要静态库
本质就是将库中的源代码直接翻译成.o目标二进制文件, 进行打包

如何制作一个库?(以完成一个计算器为例)

补充:库内没有main函数

在这里插入图片描述

现存在这样的一个项目,存在很多的.c,.h文件,所以直接编译

gcc -o test Add.c Mul.c Div.c Sub.c

可是这样存在的问题就是每一个.c文件都会形成编译汇编链接这样的步骤,所以建议
将所有的.c文件进行编译形成.o文件然后进行链接
这也是vs编译器下会存在很多.obj文件的原因
这样的好处在于多语言环境下,直接将.o文件进行链接就能形成所需的个性化功能

在这里插入图片描述

		%.o:%.c
    gcc -c $<     //将所有的.c文件通过gcc -c选项编译成对应的.o文件

在这里插入图片描述

补充:在编译时gcc -c sub.c会自动生成对应的.o文件

在这里插入图片描述

但实际上用户的使用程序并不需要.c文件,只需要这些.o文件即可
将这些.o文件进行打包,链接到自己的可执行程序即可

在这里插入图片描述

使用gcc *.o 形成可执行程序

可是当.o文件很多就不方便,所以进行打包

使用 ar指令 将所有的.o文件打包形成库文件

ar  -rc $@(目标) $^()

rc代表replace and creat

在这里插入图片描述

怎么使用静态库?

在这里插入图片描述

gcc 含有main的.c文件 -l静态库名 -L路径
针对第三方库要指明库的静态库名和路径
静态库名 libmymath.a 去掉lib,去掉.a后缀,这个静态库名称是mymath -l紧跟静态库名称 -L紧跟路径
这只是针对第三方库

ldd

查看一个可执行程序依赖的动态库文件
静态库已经到可执行程序里了,不可查
一个程序默认是动静态混合链接的
-static选项可选
没有-static表示静态库文件已经在可执行程序里面了
有-static必须全部都使用静态库,最终形成一个可执行的静态程序
默认使用动态链接的
对于一个没有-static选项时,有静态库会默认添加进去
如果没有动态库 只有一个默认的静态库加到这个程序中去

在这里插入图片描述

gcc默认是动态链接的
但个别库只提供静态库,只能局部性的将指定的.a进行链接
同时为了方便将这些.c文件都放在include文件下面,将所有的.h文件放在lib文件下面
这一步使用makefile来完成

在这里插入图片描述

演示结果:

在这里插入图片描述

查看mymath_lib的目录

在这里插入图片描述

将来想把这个项目打包发给别人可以tar czf

在这里插入图片描述
同样的,将来得到一个.tgz的压缩文件,怎么去使用呢?
tar xzf mumath_lib.tgz 进行解压缩文件
将这个文件进行解压
系统头文件在/usr/inclcude下
库文件在/usr/lib64目录下

在这里插入图片描述

将这个对应的头文件和库文件拷贝到系统对应的目录下就叫做安装了

但是这样相当于污染系统环境
所以使用的时候直接""这样包含头文件就行
在这里插入图片描述

不过这样要带上绝对路径很麻烦

要想直接#include “Add.h”
且Add.h不在当前路径下面,那么必须要

gcc test.c  -I mymath_lib/include

-I头文件路径
-l库文件名称
-L库文件路径

连起来,知道一个解压好的静态库文件,知道头文件,main文件已经写好,只差链接这一步,应该怎么c操作呢?

gcc TestMain.c -I mymath_lib/include -l mymath -L mymath_lib/lib

在这里插入图片描述

如果这个库被拷贝到系统路径下面了,那么这个-I 和 -L 的选项就不用做了

动态库

程序在运行时才去链接动态库的代码,多个程序共享使用库的代码

如何制作动态库?
与静态库一样,需要将所有源文件编成.o将所有的.o文件进行打包
细节:
1.编成的.o文件

gcc -fPIC -c *.c    //fPIC表示产生位置无关码(稍后解释)

2.进行打包(形成共享库)由此可见,动态库是更需要的一种需求,gcc不仅能编译源程序,更能打包生成动态库文件

gcc -shared -o libmymath.so

动态库生成

PS:讲一个文件内容进行备份
mv makefile makefile.backup
cp makefile.backup makefile
这样原先的makefile和makefile.backup的内容一样,完成备份

在这里插入图片描述

生成:
在这里插入图片描述

此时对应的头文件和库文件就存在了
打包使用与静态库一样.

现在,现在对这个动态库进行编译
在这里插入图片描述
生成了a,out,运行
在这里插入图片描述

出错了???

动态库和可执行程序是分离的,所以程序运行必须同时找到并加载可执行程序和库的位置
动态链接很依赖动态库

使用ldd 查看这个程序依赖的动态库

在这里插入图片描述

可以看到这个可执行程序找不到依赖的动态库,所以要给定确切的路径

总结:
动静态库在编译形成链接.o
文件时不同
在执行程序要对动态库制定动态库文件
这两点不一样

四种方法

1.将头文件和库文件放在系统路径下

在这里插入图片描述

这时在进行编译就没有编译不同的原因,而是提示库文件找不到
在这里插入图片描述

库文件找不到,接下来只要进行库文件的链接即可

在这里插入图片描述

这个库文件也能找到
在这里插入图片描述

以上均为实验,现在删除自定义库文件,头文件,防止污染系统
在这里插入图片描述
删除成功

2.软链接方式
在这里插入图片描述

当然可以选择将软链接文件放在系统路径下面(这边的路径建议从~路径开始 放置位置从/lib64开始)

在这里插入图片描述
在这里插入图片描述

同样,为防止污染系统,去掉这个软链接

在这里插入图片描述

方法三:LD_LIBRARY_PATH(加载库环境变量)
将库添加到环境变量
当执行程序的时候,./a.out说明程序已经找到,是库文件找不到
OS除了会去lib64找,还会去LD_LIBRARY_PATH下找
在这里插入图片描述

导入环境变量(只需要添加文件路径即可(跟win一样))

在这里插入图片描述

方法三在下次登录时就没有了,因为那个只是内存级,

方法四:
直接更改系统关于配置库的加载文件
这个文件的存放处在/etc/ld.so.conf.d/
在这里插入图片描述可以看到里面的文件内容只有一行数据

所以直接添加一个文件,将库路径输进去就行

在这里插入图片描述

有时候不立即显示,所以ldconfig,刷新一下

在这里插入图片描述

这种下,退出进去还是有效的

同一个库同时提供动静态库,默认使用动态库
除非

gcc TestMain.c -I mymath_lib/include/ -lmymath -L mymath_lib/lib -static

使用静态库加载程序

关于fPIC 形成位置无关码(下章见分晓)~~~

创作不易,来个三连支持一下吧~~~

  • 34
    点赞
  • 41
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

温有情

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值