Linux学习之makefile
写在前面:
我的Linux的学习之路非常坎坷。第一次学习Linux是在大一下的开学没多久,结果因为不会安装VMware就无疾而终了,可以说是没开始就失败了。第二次学习Linux是在大一下快放暑假(那个时候刚刚过完考试周),我没什么事做就又重拾Linux,不服输的我选择再战Linux,这一次学习还算顺利,虽然中间有些小插曲但是不影响整体学习进度, 我看着B站上的视频一点点学习Linux,基本上把Linux的基础指令学完了。学完之后我又遇到问题了,视频基本上到这就结束了,而我却不知道下一步该学什么,于是就没怎么碰Linux,结果没过多长时间我就把学的Linux指令忘的一干二净。现在是我第三次学习Linux,我决定重新开始学Linux,同时为了让自己学习的效果更好,我选择以写blog的形式逼迫自己每天把学习到的Linux知识整理下来。这也就是我写这个系列blog的原因。
makefile的基础规则
makefile:项目管理
命令:makefile or Makefile —make命令
- 一个规则:
目标:依赖条件
(一个tab缩进)命令- 目标的时间必须晚于依赖条件,否则,更新目标。
- 依赖条件如果不存在,寻找新的规则去生成依赖条件。
- 两个函数:
src=$(wildcard ./*.c)
:寻找当前目录下的所有.c
文件,将文件名组成列表,赋值给变量src
obj=$(patsubst %.c %.o $(src))
: 将参数3中所有包含参数1的部分替换成参数2
- 三个自动变量:
$@
:在规则的命令中,表示规则中的目标。$^
:在规则的命令中,表示所有的依赖条件。$<
:在规则的命令中,表示第一个依赖条件。如果将该变量应用于模式规则中,它可将依赖条件列表中的依赖一次取出,套用模式规则。
- 模式规则:
%.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
命令
上机操作
第一版
- 编写
nakefile
文件
makefile
的依赖的从上至下的,换句话说就是目标文件是第一句里的目标,如果不满足执行依赖,就会继续向下执行。如果满足了生成目标的依赖,就不会再继续向下执行了。make
会自动寻找规则里需要的材料文件,执行规则下面的行为生成规则中的目标。
- 执行
make
命令
- 执行生成的
test
第二版
- 我们上点强度,修改下
test
,修改后需要多文件联合编译。
- 此时就要联合多文件编译,我们先从简单的来,先想想我们在之前用
gcc
是怎么写的,我们就怎么写到makefile
- 执行
make
第三版
在实际开发中,有可能add.c
会有些许改动。但是如果是第二版的话,我们就要把所有的文件都在编译一遍,这非常浪费时间,非常蠢。之前我们学到编译的四个步骤中第二步是最好时间的,所以我们可以把步骤拆分。
- 修改
makefile
,将步骤拆分
- 修改
add.c
,看实际效果
我们可以看到修改add,c
之后,我们再make
就只是把add.c
和test.o add.o sub.o mul.o div1.o
再重新编译了一下,这就节省不少时间。
原因
makefile
检测原理:修改文件后,文件的修改时间发生变化,会出现目标文件的时间早于依赖文件的时间,出现这种情况的文件会重新执行规则,重新编译。例如上面,我修改add.c
后,add.c
的文件时间就晚于add.o
,这种情况下就重新编译生成add.o
,而其他文件时间符合,就不变。
第四版
有童鞋可能会问我们之前介绍的函数还没有发挥作用,别急,接下来我就为你介绍怎么把函数用到makefile
里面。
- 修改
makefile
,使用函数
src = add.c sub.c mul.c div1.c
obj = add.o sub.o mul.o div1.o
- 执行
make
- 执行
./test
,效果和之前和一样,我这里就不演示了。
pay attention: 在使用
wildcard
和patsubst
函数参数之间不要随便加空格,严格按照我的格式来。(因为我一开始学的时候,我多加了个空格,结果debug了半天,心态差点炸了)
第五版
先来重温一下前面讲的三个自动变量:
$@
:在规则命令中,表示规则中的目标$^
在规则命令中,表示规则中的所有条件,组成一个列表,以空格隔开,如果这个列表中有重复项,则去重$<
::在规则命令中,表示规则中的第一个条件,如果将该变量用在模式规则中,它可以将依赖条件列表中的依赖依次取出,套用模式规则
- 修改
makefile
,使用三个自动变量
- 执行
make
- 执行
./test
,效果和之前是一样的,我这里就不展示了。
sub,add
这些指令中使用$<
和$^
都能达到效果,但是为了模式规则,所以使用的$<
第六版
很多人以为第五版是最终版,但其实不是,因为第五版的可拓展性太差了,比如在加一个功能(如取模运算)的函数就需要再增加取模函数部分,这很蠢,所以,模式规则来了。
- 修改
makefile
,套用模式规则。
%.o : %.c
gcc $< -o $@
- 执行
make
,执行生成的文件。
- 添加一个运算,取模。我们只需要写好源代码,修改
test.c
,然后直接make
即可,不用改makefie
,这就很nice
第七版
第七版是对第六版的优化,以后文件集合会有很多,我们就需要指定哪个文件集合使用哪个规则,这就要用到静态模式规则。
- 修改
makefile
,指定模式规则给obj
用。
写在最后
个人亲身经验:我们学习的一系列Linux命令,一定要自己亲手去敲。不要只是看别人敲代码,不要只是停留在眼睛看,脑袋以为自己懂了,等你实际上手去敲会发现许许多多的这样那样的问题。正可谓“键盘敲烂,月薪过万”
如果你觉得我写的题解还不错的,请各位王子公主移步到我的其他题解看看
- 数据结构与算法部分(还在更新中):
- C++ STL总结 - 基于算法竞赛(强力推荐)
- 动态规划——01背包问题
- 动态规划——完全背包问题
- 动态规划——多重背包问题
- 动态规划——分组背包问题
- 动态规划——最长上升子序列(LIS)
- 二叉树的中序遍历(三种方法)
- 最长回文子串
- 最短路算法——Dijkstra(C++实现)
- 最短路算法———Bellman_Ford算法(C++实现)
- 最短路算法———SPFA算法(C++实现)
- 最小生成树算法———prim算法(C++实现)
- 最小生成树算法———Kruskal算法(C++实现)
- 染色法判断二分图(C++实现)
- Linux部分(还在更新中):
?🎉总结
“种一颗树最好的是十年前,其次就是现在”
所以,
“让我们一起努力吧,去奔赴更高更远的山海”
如果有错误?,欢迎指正哟😋
🎉如果觉得收获满满,可以动动小手,点点赞👍,支持一下哟🎉
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。 如若内容造成侵权/违法违规/事实不符,请联系我的编程经验分享网邮箱:veading@qq.com进行投诉反馈,一经查实,立即删除!