Linux开发工具Make/Makefile篇

28 篇文章 2 订阅

在这里插入图片描述

🍈0. 前言

我们使用gcc/g++编译代码时,每次都要输入一长串的指令,对于单个文件或者文件较少的时候,我们还能接受,可是当文件较多的时候,我们再一个一个编译,就会比较麻烦。Linux中make命令加上Makefile文件搭配使用,就可以完成项目的自动化构建。

🍉1. 见见猪跑

C代码

#include<stdio.h>
int main()
{
	printf("hello linux\n");
	printf("hello linux\n");
	printf("hello linux\n");
	return 0;
}

创建makefile文件

mkdir makefile

写入依赖关系、依赖方法

code:code.c
	gcc -o code code.c
clean
	rm -f code

执行make命令

image-20230706141348815

这一套流程下来,就是简单的自动化编译与清理,这里要清楚的是make是一个命令,而makefile是一个文件。下面我们来讲解一下这其中原理。

🍊2. 依赖关系和依赖方法

打个比方:

期末考试考完了,在路上碰见了老师,你想求老师捞一捞。上前打招呼,“老师,我是你学生xxx”,这句话就是说明你和这个老师的关系,这个就是依赖关系

答完招呼,你就说出了你的想法,“老师,捞一把,卷子我全部都写满了”,老师说“好的好的,我尽量,我尽量”。而这个向老师提出的需求就是依赖方法

image-20230706144218282

知道了这个概念,再来看一下其中的流程,将makefile文件写的复杂一点

code:code.o
	gcc -o code code.o
code.o : code.s
	gcc -c code.s -o  code.o
code.s : code.i
	gcc -S code.i -o code.s
code.i : code.c
	gcc -E code.c -o code.i

然后我们再执行make指令:

image-20230706151232954

我们发现,如果按顺序来执行的话,应该是先执行gcc -o code code.c,但是这个输出的顺序并不是这样,而是反正输出的。

这里其实是因为code依赖的是code.o文件,而当前目录并没有这个文件,于是需要生成一个code.o的文件,发现依赖文件中有生成code.o的依赖关系和依赖方法,依次类推。这就很像递归的过程

所以我们可以知道make会自动的推导makefile中的依赖关系,而这种过程是一种栈式的结构

Tips:

即使我们调换了其中的顺序,也可以生成,就类似调用函数,不管这个函数在哪,只要能调到就行;

但是如果这其中缺少了环节,那么就不会生成了。

image-20230706153940612

当然了,这只是演示,在实际操作的时候,就不要写这么复杂,能一步到位就一步到位。

🍋3. 清理

当项目不要的时候,需要进行清理。我们就可以到makefile文件中写入清理的依赖关系和依赖方法:

clean:
	rm -f code code.i code.o code.s

clean不需要依赖其他的文件,依赖关系为空

执行make clean指令,就删除了我们不需要的项目文件。

image-20230706155318132

那为啥清理的时候需要make clean呢?能不能也像创建可执行文件时,直接使用make呢?

我们将makefile文件稍微下一下,将clean移到最前面来,然后再执行make指令:

image-20230706155921450

这样我们使用make的时候,就默认变成了清理操作。

这是因为make会自顶向下去扫描,将第一个依赖充当为默认操作

🍌4. 不可多次编译的原理

🍍4.1 原因

image-20230706161016574

当我们多次make时,系统会提示我们code是最新的,就不让我们继续make了。

如果将code.c文件修改一下,会发现又能重新make了,但也是只能make一次。

image-20230706161403362

出现这种情况是因为编译器认为没有必要,既然文件没有发生改变,那就没有必要再编译一次,就算编译了,也是一样的,所以为了节省资源,编译器就会选择不编译,出发这个文件内容发生改变。

VS2022为例:

1

那这是如何做到的呢?

对于源文件生成可执行程序,那么肯定是先有源文件,再有可执行程序,在这种情况下,源文件的修改时间肯定是在可执行程序之前

如果修改了源文件,那么源文件的修改时间肯定会比可执行程序要新

所以,这需要比较源文件和可执行程序的最近修改时间就行。

🍍4.2 stat命令

stat命令可以查看文件的详细信息,这里面就包含了文件的时间信息。

image-20230706191448757

  • Access:最近访问时间(打开、查看、修改),只要我们访问了该文件,就会被记录。

只要访问文件,Access就会改变,当多人协同操作的时候,有些文件可能会被频繁的访问,如果每次访问就修改时间,那么就每次都要去磁盘修改文件的属性,这就会十分影响效率。

在较新的版本中,Access的更新策略发生了改变,会根据ModifyChange的改变或者采用计数器等方式改变。

image-20230706202021463

  • Modify:对文件内容继续修改的时间

  • Change:文件属性改变的时间

image-20230706200108067

文件内容改变的时候,文件属性肯定会改变;文件属性改变,不一定会改变文件内容

image-20230706202655221

touch 文件名如果没有该文件,则创建该文件;

如果有了这个文件,则更新所以最新时间。

image-20230706202945963

🍍4.3 验证

了解了文件的时间关系,就能够解释前面的原因了,我们来验证一下

image-20230706204104579

🥭5. 伪目标

如果我们不想受这个的约束,想执行就执行,可采用.PHONY来修饰这个目标文件,让其是一个伪目标。

image-20230706204539503

当然,这里不建议将我们的可执行操作设为伪目标,一般采用将清理操作设为伪目标。

image-20230706205935176

🍎6. 取消回显

我们使用make时,每次都会将对应的方法回显出来,如果不想要回显,我们可以将依赖方法前面加上@

另外,使用$@(:$^自动化变量,引用目标和依赖项。

image-20230706211001200




以上就是make的基本操作了,大伙可以根据项目的实际需求和复杂性来扩展和定制Makefile。

那本次的分享就到这里啦,如果要帮助的话希望点赞支持一下,我们下期再见,如果还有下期的话。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

加法器+

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

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

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

打赏作者

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

抵扣说明:

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

余额充值