Linux学习之制作静态库和动态库

写在前面:

我的Linux的学习之路非常坎坷。第一次学习Linux是在大一下的开学没多久,结果因为不会安装VMware就无疾而终了,可以说是没开始就失败了。第二次学习Linux是在大一下快放暑假(那个时候刚刚过完考试周),我没什么事做就又重拾Linux,不服输的我选择再战Linux,这一次学习还算顺利,虽然中间有些小插曲但是不影响整体学习进度, 我看着B站上的视频一点点学习Linux,基本上把Linux的基础指令学完了。学完之后我又遇到问题了,视频基本上到这就结束了,而我却不知道下一步该学什么,于是就没怎么碰Linux,结果没过多长时间我就把学的Linux指令忘的一干二净。现在是我第三次学习Linux,我决定重新开始学Linux,同时为了让自己学习的效果更好,我选择以写blog的形式逼迫自己每天把学习到的Linux知识整理下来。这也就是我写这个系列blog的原因。

动态库和静态库的理论对比

  • 静态库在文件中静态展开,所以有但多少文件就展开多少次,非常吃内存,100M的文件展开一百次就是1G。但是这样的好处是静态加载的速度快
  • 动态库使用时,会讲动态库加载到内存,10个文件也只需要加载一次,然后将这些文件用到库时候临时去加载,速度慢一些但是很省内存
    总述

静态库的制作

  1. 写好源代码。下面我以写一个可以四则运算的静态库的为例)
    源码

  1. 编译源代码生成 .o文件。
    编译生成

可能有些童鞋没学过编译的四个过程,下面我来介绍一下

  1. 预处理: 展开宏,头文件,替换编译条件,删除注释,空行,空白。
  2. 编译: 检查语法规范。
  3. 汇编: 将汇编指令翻译成机器指令。
  4. 链接: 数据段合并,地址回填。

gcc


关于gcc常用的编译参数

  • -I:指定头文件所在目录位置。
  • -c:只做预处理,编译,汇编。得到二进制文件。
  • -g:编译时添加调试文件,用于 gdb 调试。
  • -Wall:显示所有警告信息。
  • -D:向程序中“动态”注册宏定义
  • -L:指定动态库路径。
  • -l:指定动态库库名。

  1. 制作静态库
    命令:ar rcs lib库名.a file1.o file2.o ...
    3

  1. 制作头文件
    如果我们直接使用静态库gcc test.c lib库名.a -o a.out,就会有以下警告。
    4
    为了防止出现以上警告,我们就要做一个头文件来包含函数声明(当然你也可以直接在test中声明,但这体现我们的水平😁)
    5

左边的 define 为头文件守卫,防止在代码中多次 include 头文件,多次展开静态库,带来的额外开销

接下来我们再来编译,这样就不会就有警告报错了。
6

最后-I ...是写头文件的地址


动态库的制作

  1. 编写源代码
    1

  1. 生成位置无关的.o 文件
    命令:gcc -c add.c -o add.o -fPIC

使用这个参数-fPIC过后,生成的函数就和位置无关,挂上@plt 标识,等待动态绑定
2


  1. 使用制作动态库
    命令:gcc -shared -o lib库名.so file1.o file2.o ....
    1

  1. 编译程序
    命令:gcc test,c -o test -l 库名 -L 路径 -I 头文件的位置

  1. 执行文件,然后出错😂。
    2

  1. 出错原因及解决方法
  • 出错原因分析:
    • 连接器:工作于链接阶段,工作时需要 -l 和 -L
    • 工作于程序运行阶段,工作时需要提供动态库所在目录位置
  • 解决方法:
    1. 通过环境变量指定动态库所在位置:export LD_LIBRARY_PATH=动态库路径。但是这个方法有个弊端,当关闭终端,再次执行a.out 时,又报错。这是因为,环境变量是进程的概念,关闭终端之后再打开,是两个进程,环境变量发生了变化。
      3
    2. 写入终端配置文件。 步骤如下:
      • vi ~/.bashrc
      • 写入 export LD_LIBRARY_PATH=动态库路径
      • . .bashrc/ source 或者.bashrc / 或者重启 终端 —> 让修改后的.bashrc 生效
      • ./a.out 成功!!!
    3. 配置文件法。步骤如下:
      • sudo vi /etc/ld.so.conf
      • 写入 动态库绝对路径 保存
      • sudo ldconfig -v 使配置文件生效。
      • ./a.out 成功!!!— 使用ldd a.out查看

写在最后

个人亲身经验:我们学习的一系列Linux命令,一定要自己亲手去敲。不要只是看别人敲代码,不要只是停留在眼睛看,脑袋以为自己懂了,等你实际上手去敲会发现许许多多的这样那样的问题。正可谓“键盘敲烂,月薪过万


如果你觉得我写题解还不错的,请各位王子公主移步到我的其他题解看看

  1. 数据结构与算法部分(还在更新中):
  1. Linux部分(还在更新中):

✨🎉总结

“种一颗树最好的是十年前,其次就是现在”
所以,
“让我们一起努力吧,去奔赴更高更远的山海”
在这里插入图片描述
如果有错误❌,欢迎指正哟😋

🎉如果觉得收获满满,可以动动小手,点点赞👍,支持一下哟🎉

  • 31
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值