前往小程序,Get更优阅读体验!
立即前往
发布
社区首页 >专栏 >解锁动静态库的神秘力量1:从代码片段到高效程序的蜕变

解锁动静态库的神秘力量1:从代码片段到高效程序的蜕变

作者头像
用户11458826
发布2025-01-23 19:02:20
发布2025-01-23 19:02:20
4800
代码可运行
举报
文章被收录于专栏:杀马特杀马特
运行总次数:0
代码可运行

本篇博主将带大家基于linux系统方面了解动静态库是什么,怎么创建以及如何使用等一些注意事项,希望能对大家在这方面的学习有所帮助。

一·库的含义及分类:

库是写好的现有的,成熟的,可以复⽤的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个⼈的代码都从零开始,因此库的存在意义⾮同寻常。

本质上来说库是⼀种可执⾏代码的⼆进制形式,可以被操作系统载⼊内存执⾏。库有两种:

静态库 .a[Linux]、.lib[windows] 动态库 .so[Linux]、.dll[windows]

也可以理解为.o系列文件集合打包;那么为啥需要库呢?

因为如果有多个.c文件或者很多都要复用这些,那么总是把它们一同编译就显得有点冗余了;因此不妨使用库。

假设没有库,对于一堆维.c文件我们就直接gcc一步处理成可执行程序,然后运行(. h必须要在当前目录否则找不到) :

下面我们来以一些测试代码带大家进行讲解工作:

1.1静态库的形成与使用:

下面我们从这两方面带大家理解静态库:

静态库(.a):程序在编译链接的时候把库的代码链接到可执⾏⽂件中,程序运⾏的时候将不再需要静态库。

这里静态库是直接拷贝到可执行程序中,gcc找到后完成编译,程序就可以跑,不需要运行exe时系统再去找库,但是动态库需典 。

说白了就是静态库会把对应的那一堆.o文件拷贝进可执行文件(这里对于动态库就不行了,后面我们细讲)。

其次就是,我们静态库要有lib和以.a后缀,然而库名是去掉这些。

下面形成静态库需要这几步: 1·把全部.c文件编译成.o。 2·把.o文件都打包生成静态库。 3·使用静态库与目标文件链接形成可执行程序。

这样我们就生成了.o文件。

完成静态库的形成。

使用静态库去和其他文件链接:

这样就可以跑起来了:

其实也是非常简单的。

1.2动态库的形成与使用:

步骤和上面静态库的大差不大,只是有些地方需要改动一下:

这里的-fPIC也是不可少的:

形成动态库(注意这里库名后缀改成了so,此外还多加了-shared):

接下来我们就去链接了:

但是生成的可执行程序p不能运行?

下面我们来查看一下可执行程序的动态链接情况:

这里发现所要动态链接的动态库无法找到,为什么呢? GCC!=系统;静态库,系统可以从EXE中找到但是动态库找不到 。

这是因为动态库并没有像静态库那样拷贝进p文件;而是动态连接;链接的时候只是告诉gcc了这个库的位置;而运行的时候是系统干的,它不知道动态库位詈。

那就引出了我们下面的工作,就是去帮助系统运行可执行文件的时候找到动态库。

二·系统如何查找动态库 :

下面我们分四中方法来完成帮助系统寻找工作:

2.1.拷贝到系统lib库:

这里我们首先要知道,系统在运行可执行文件的时候先去lib库内看看有没有这个库:

下面我们就查看一下系统的lib库:

找到后我们把当前路径的动态库文件拷贝进去:

然后我们再次运行:

这里一般我们安装程序等,系统都会采用这种方法把动态库装到lib库内。

2.2建立软链接:

之前博主出了一片Ext2文件系统的文章里面会对软硬链接有所介绍,不懂的朋友们可以去看一下,传送门:Ext2 文件系统:数字世界的基石,深度解码超时空存储魔法-CSDN博客

这里需要注意的是我们软链接的文件(没有就生成)必须与我们的库名一样,因为此刻系统在lib库找个库名;这样我们通过软链接的性质就得到了这个动态库。

2.3安置环境变量:

这里系统还会在它自己的环境变量:LD_LIBRARY_PATH中查找是否有有关动态库的路径;因此我们可以把此路径导入进去即可。

这样就能跑了;为了不干扰后面,我们在unlink掉:

2.4 ldconfig⽅案:

系统一开始还会往这里面的.conf文件里找看是否存在动态库的路径,并沿着路径找动态库 。

因此我们只需要加入一个.conf结尾的配置文件加入动态库的路径即可。

完成添加.conf配置文件并写入路径:

此时程序还是不能跑的,因为我们没有进行刷新配置文件;此刻调用ldconfig刷新一下:

三·一些有关小指令:

ldd +可执行文件 :查看可执行文件的动态链接情况

size +可执行文件:显示目标文件(包括可执行文件)中各个段(section)的大小,以及总的大小。这些段通常包括代码段(text)、数据段(data)、BSS 段(未初始化数据)等。

file+文件:file命令可以用于确定文件类型。它通过检查文件的内容(如文件头、魔数等)来判断文件是何种类型的可执行文件(例如是 ELF 格式的可执行文件、脚本文件还是其他格式)。

四·动静态库同时存在系统行为:

因此大家肯定有个疑问,如果动静态库同时存在且名字相同,那么系统默认会怎么做呢?下面演示一下:

这里报错是无法找到动态链接,故看来系统是默认动态链接了;因此系统优先考虑的是动态库;那么当我们安装程序等的时候系统也会优先对它进行动态库安装以及链接等。

如果我们就是想用动态的话;可以-static 强转一下:

这里就是告诉系统要用静态链接了。

五·目标文件分步编译和链接 :

肯定大家有个疑问,为什么把它们俩分开呢?

假设我们有大量.c文件都编译成了.o文件然后有个.c错了,我们只需要修改其中一个然后再搞成.o与其他大量.o文件进行链接就好;但是如果这两个过程在一起就麻烦了。

六·简单实现库的打包安装及使用:

下面我们以静态库为例演示压下(动态库只需要稍微变动一下即可):

Makefile文件:

代码语言:javascript
代码运行次数:0
复制
libmy.a:print.o print2.o
	@ar -rc $@ $^
%.o:%.c
	@gcc -c $<
.PHONY:output
output:
	@mkdir -p ku/head
	@mkdir -p ku/lib
	@cp -f *.a ku/lib
	@cp -f *.h ku/head
	@tar -czf lib.tgz ku
	@rm -rf ku
	@rm -rf *.a
.PHONY:clean
clean:
	@rm -rf *.a *.o lib.tgz d/ku p

此时的我们:

下面我们来把静态库生成并且解压运行一下:

形成静态库:

打包成压缩包:

把它解压到d目录内:

静态库链接并执行:

清理工作:

本期分享结束了,但是动静态库系列并没有,下面我们就期待博主更新动静态库第二讲吧;欢迎大家阅读!!!

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2025-01-23,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一·库的含义及分类:
  • 1.1静态库的形成与使用:
  • 1.2动态库的形成与使用:
  • 二·系统如何查找动态库 :
  • 2.1.拷贝到系统lib库:
  • 2.2建立软链接:
  • 2.3安置环境变量:
  • 2.4 ldconfig⽅案:
  • 三·一些有关小指令:
  • 四·动静态库同时存在系统行为:
  • 五·目标文件分步编译和链接 :
  • 六·简单实现库的打包安装及使用:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档