Linux学习之makefile

发布时间:2023年12月29日

写在前面:

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


makefile的基础规则

makefile:项目管理
命令:makefile or Makefile —make命令

  • 一个规则
    目标:依赖条件
    (一个tab缩进)命令
    1. 目标的时间必须晚于依赖条件,否则,更新目标。
    2. 依赖条件如果不存在,寻找新的规则去生成依赖条件。
  • 两个函数
    1. src=$(wildcard ./*.c):寻找当前目录下的所有.c文件,将文件名组成列表,赋值给变量src
    2. obj=$(patsubst %.c %.o $(src)): 将参数3中所有包含参数1的部分替换成参数2
  • 三个自动变量
    1. $@:在规则的命令中,表示规则中的目标。
    2. $^:在规则的命令中,表示所有的依赖条件。
    3. $<:在规则的命令中,表示第一个依赖条件。如果将该变量应用于模式规则中,它可将依赖条件列表中的依赖一次取出,套用模式规则。
  • 模式规则
%.o : %.c
	gcc -c $< -o %@
  • 静态模式规则
$(obj) : %.o : %.c
	gcc -c $< -o %@
  • 终极目标:
    ALL : 最终的目标
  • 伪目标:
    .PHONY: clean ALL
  • 清除:
clean : (没有依赖)
	-rm -rf $(obj) a.out

-的作用的删除不存在的文件不报错,顺序执行结束。

  • 一些参数:
    • -n:模拟执行make make clean命令
    • -f: 指定文件执行 make命令

上机操作

第一版

  1. 编写nakefile文件
    1

makefile 的依赖的从上至下的,换句话说就是目标文件是第一句里的目标,如果不满足执行依赖,就会继续向下执行。如果满足了生成目标的依赖,就不会再继续向下执行了。make 会自动寻找规则里需要的材料文件,执行规则下面的行为生成规则中的目标。

  1. 执行make命令
    2
  2. 执行生成的test
    3

第二版

  1. 我们上点强度,修改下test,修改后需要多文件联合编译。
    1
  2. 此时就要联合多文件编译,我们先从简单的来,先想想我们在之前用gcc是怎么写的,我们就怎么写到makefile
    2
  3. 执行make
    3

第三版

在实际开发中,有可能add.c会有些许改动。但是如果是第二版的话,我们就要把所有的文件都在编译一遍,这非常浪费时间,非常蠢。之前我们学到编译的四个步骤中第二步是最好时间的,所以我们可以把步骤拆分。

  1. 修改makefile ,将步骤拆分
    1
  2. 修改add.c,看实际效果
    2
    我们可以看到修改add,c之后,我们再make就只是把add.ctest.o add.o sub.o mul.o div1.o再重新编译了一下,这就节省不少时间。

原因
makefile 检测原理:修改文件后,文件的修改时间发生变化,会出现目标文件的时间早于依赖文件的时间,出现这种情况的文件会重新执行规则,重新编译。例如上面,我修改add.c后,add.c 的文件时间就晚于add.o,这种情况下就重新编译生成add.o,而其他文件时间符合,就不变。


第四版

有童鞋可能会问我们之前介绍的函数还没有发挥作用,别急,接下来我就为你介绍怎么把函数用到makefile里面。

  1. 修改makefile,使用函数
    1

src = add.c sub.c mul.c div1.c
obj = add.o sub.o mul.o div1.o

  1. 执行make
    2
  2. 执行./test,效果和之前和一样,我这里就不演示了。

pay attention: 在使用wildcardpatsubst 函数参数之间不要随便加空格,严格按照我的格式来。(因为我一开始学的时候,我多加了个空格,结果debug了半天,心态差点炸了)


第五版

先来重温一下前面讲的三个自动变量

  • $@:在规则命令中,表示规则中的目标
  • $^在规则命令中,表示规则中的所有条件,组成一个列表,以空格隔开,如果这个列表中有重复项,则去重
  • $<::在规则命令中,表示规则中的第一个条件,如果将该变量用在模式规则中,它可以将依赖条件列表中的依赖依次取出,套用模式规则
  1. 修改makefile,使用三个自动变量
    1
  2. 执行make
    2
  3. 执行./test,效果和之前是一样的,我这里就不展示了。

sub,add 这些指令中使用$<$^都能达到效果,但是为了模式规则,所以使用的$<


第六版

很多人以为第五版是最终版,但其实不是,因为第五版的可拓展性太差了,比如在加一个功能(如取模运算)的函数就需要再增加取模函数部分,这很蠢,所以,模式规则来了。

  1. 修改makefile,套用模式规则。
%.o : %.c
	gcc $< -o $@

1

  1. 执行make,执行生成的文件。
    2
  2. 添加一个运算,取模。我们只需要写好源代码,修改test.c,然后直接make即可,不用改makefie,这就很nice
    3

第七版

第七版是对第六版的优化,以后文件集合会有很多,我们就需要指定哪个文件集合使用哪个规则,这就要用到静态模式规则。

  1. 修改makefile,指定模式规则给obj用。
    1

写在最后

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


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

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

?🎉总结

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

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

文章来源:https://blog.csdn.net/yourgrandfather_/article/details/135288190
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。