您好,欢迎来到纷纭教育。
搜索
您的当前位置:首页【Linux系统编程】Linux项目自动化构建工具——make/Makefile

【Linux系统编程】Linux项目自动化构建工具——make/Makefile

来源:纷纭教育


我们继续Linux开发工具的学习,这篇文章我们要学的是Linux中的项目自动化构建工具——make/Makefile

1. 背景

make和makefile提供了自动化构建的能力,可以根据源文件的依赖关系和规则自动决定哪些文件需要重新编译。而直接使用gcc需要手动指定每个源文件的编译命令,不具备自动化的构建功能。

make是一条命令,makefile是一个文件,两个搭配使用,完成项目自动化构建。

也就是说,想完成项目的自动化构建,我们需要两个东西

一个是make,它是一条指令,那我们到时候可以直接用,另一个是makefile,它是一个文件,这个文件由我们自己创建,一般就直接创建在当前源代码所在路径下

那具体要怎么做呢?
接下来我们先给大家演示一下,然后再具体解释

2. 使用演示

2.1 生成

接下来就先给大家演示一下:

首先这里已经有一份源代码了

那这就写完了,我们保存退出

然后我们现在想把myfile.c生成可执行程序,直接make就行(它就会自动去执行Makefile里面的gcc命令)

我们看到,可执行文件myfile就生成了

2.2 清理

那如果我想把生成的myfile清理掉呢?

正常我们可以使用rm命令删除文件。

但其实我们也可以把它放到Mkfile里面

vim打开Makefile,这样写

此时我们想清理的话:

直接make clean

后续,如果我们修改了源文件

3. 语法及概念介绍

3.1 makefile 的语法

然后,我们再回过来看Makefile,它为什么要那样写呢?该怎么理解呢?

我们打开它:


接下来我们就来解释一下

首先看第一行,为什么这样写呢?
语法:

target: dependencies
    command

target是目标文件名,dependencies是目标文件依赖的文件列表(如果有多个用空格隔开),command是构建目标文件的命令(记得前面加Tab)。
那对应我们写的:

即myfile是由myfile.c得到的;myfile是目标文件,myfile.c是目标文件形成需要依赖的文件,第二行gcc myfile.c -o myfile就是构建目标文件的命令。

我们把目标文件和他所依赖的文件列表之间的关系称为依赖关系,对应的命令称为依赖方法

所以:
makefile是一个国绕依赖关系和依赖方法构建的一个自动化编译的工具

3.2 依赖关系与依赖方法的理解

那么我们该怎么理解依赖关系和依赖方法这两个名词呢?

下面通过一个例子帮助大家理解一下:
假设你在学校上学,到月底了,你钱花光了,于是就打算给你爸爸打电话要钱。
但是呢,电话接通,你只给你爸说了一句:“是我啊老爸,您儿子”。
然后就直接把电话挂了。
那你觉得你问你爸要钱这件事能办成嘛?
显然不能,因为你只跟你爸表明了依赖关系,你爸并不能知道你想干嘛。
所以,正常情况下,只有依赖关系是做不成一件事的。
你除了跟你爸说你是谁之外,你还应该说:“我的生活费花完了,你给我打点钱吧”。
这样你爸才会给你打钱。
后半句话,就可以认为是依赖方法。
但是,如果你给你爸打电话说:我是你儿子,所以你应该给我写作业。那这个依赖方法显然是不合理的,你可能会挨一顿打。
又或者你给你室友的爸爸打电话,让人家给你打钱,那你的依赖关系肯定是不正确的。
所以正常情况下,同时具备了正确的依赖关系和正确的依赖方法,才能做出一件事。

所以,在这里也是一样:


你想得到可执行程序,得有源代码啊(依赖关系),有了源代码,你得用编译器去编译链接啊(依赖方法)。
然后make命令,它会自动分析文件的依赖关系,决定哪些文件需要重新编译,然后执行相应的构建规则。

所以,总结一下:

make是一个基于文件依赖关系的构建工具,它可以根据指定的规则和条件来自动更新程序的部分或全部,从而减少手动编译的工作量。通过使用make,你可以只重新编译已修改的源文件,而不是整个项目,提高了编译的效率。
makefile是一个文本文件,它包含了构建目标(target)和构建规则(rule)。在makefile中,你可以定义编译器的选项、源文件的依赖关系以及如何生成可执行程序等内容。make命令会读取makefile文件并根据其中的规则来进行构建。

使用make和makefile的主要步骤如下:

创建一个makefile文件,并为各个目标指定构建规则。
在makefile中定义源文件之间的依赖关系以及对应的编译命令。
运行make命令,它会自动分析文件的依赖关系,决定哪些文件需要重新编译,然后执行相应的构建规则。

3.3 make 的工作原理

接下来我把上面写的Makefile修改一下:

大家想一下,如果我们想生成可执行文件,除了可以依赖源文件myfile.c之外,还可以依赖什么?
是不是还可以是myfile.o啊,因为.o链接之后就成可执行exe了嘛。

但是这样写的话,我们没有myfile.o
那就要先生成myfile.o

那这样又要先生成myfile.s

那要先生成myfile.i

所以是这样的。
从上到下就像是一个压栈的过程,而最后执行的顺序其实就是出栈的顺序。

我们可以看一下:


执行make之后显示的其实就是执行的顺序

make是如何工作的,在默认的方式下,也就是我们只输入make命令。那么:

3.4 依赖文件列表可以为空

我们刚开始演示的时候其实也演示过清理了,那现在针对刚才的那个例子,我们来写一下清理:

首先,我们上面说了,正常情况下,需要同时具备正确的依赖关系和正确的依赖方法。
但其实也有特殊情况:
在makefile中,依赖文件列表可以为空,表示目标文件没有任何依赖。

那清理操作其实就是这样

通常情况下,clean规则的依赖文件列表为空,因为清理操作不依赖于其他文件。
所以,clean我们直接这样写就行

然后,我们make clean的时候,他就会自动执行clean对应的依赖方法

3.5 make默认只执行makefile文件中的第一个目标规则

那经过上面的学习,不知道大家有没有这样的疑惑:

为什么我们刚才执行生成操作的时候直接make就行了,而清理的时候是make clean,要把clean加上?
这是因为:
在终端中运行make命令时,我们可以指定目标。如果没指定,默认情况下,它只会执行makefile文件中的第一个目标规则。
而我们上面写的,生成myfile的目标规则是在第一个,而清理的在后面,所以,我们不指定的话,默认执行的就是第一个即生成myfile的操作。

那大家可以试一下:

如果你把清理放在第一个的话,我们直接make,执行的就是清理了。
你要想生成myfile,就需要显示指定了:make myfile
但是,我们一般把清理的规则放在最后。

3.6 伪目标

另外:

一般clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的。

什么意思呢?


还是以这个为例
大家看

我两次执行make(不指定默认是第一个即make myfile),有什么不同。
第一次make执行了makefile文件中的第一个目标规则,并生成了对应的文件。
但是第二次make,并没有执行对应的操作,而是告诉我们:
myfile' is up to date.——myfile已经是最新的
意思就是生成的myfile是最新的了,没必要在重新生成了。

那大家还记不记得我们最开始演示的:


这里面的clean我们多加了一个修饰 .PHONY
而我们刚才也提到:
一般clean的目标文件,我们将它设置为伪目标,用 .PHONY 修饰,伪目标的特性是,总是被执行的。
也就是说被 .PHONY 修饰后它的特性是总是被执行的。

那总是被执行的是什么意思呢?

我现在再用 .PHONY 修饰clean

然后执行make clean
我们发现它可以连续执行,即使被清理过了,还可以执行成功

而我们的make:


我们看到第一次可以执行,后面如果没有对源文件进行删除修改的话,就不能在执行了。
那这就不是总是被执行的
如果也把myfile加上.PHONY修饰的话:

他就变成总是被执行了。

那现在问题来了:我们myfile不加.PHONY修饰的时候,make执行一次之后,再执行的话就不行了,他告诉我们已经是最新的了。

3.7 touch更改文件时间

那它是怎么知道当前产生的文件已经是最新的了?

其实大家试一下就会发现,如果我们make之后,再去修改一下源文件的话,其实就可以继续make了。
因为源代码修改了,之前产生的可执行文件就不是最新的了。

所以它其实是通过对比源代码最后一次被修改的时间和可执行程序生成的时间来确定生成的可执行程序是不是最新的。
第一次生成可执行程序,文件生成时间肯定比源代码修改保存的时间新,所以你再make他就不让你make了,因为此时的可执行文件就是最新的了。
但是如果后面我们修改了源代码,那此时源代码的修改时间就比可执行程序生成的时间更新了,所以这种情况我们是可以重新make的。

那如果我们不修改源代码,能不能修改文件的时间呢?

因篇幅问题不能全部显示,请点此查看更多更全内容

Copyright © 2019- fenyunshixun.cn 版权所有 湘ICP备2023022495号-9

违法及侵权请联系:TEL:199 18 7713 E-MAIL:2724546146@qq.com

本站由北京市万商天勤律师事务所王兴未律师提供法律服务