Linux:自动化构建工具make/Makefile

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

文章目录

一.前言

在此之前我们已经可以用vim编写代码和用gcc编译代码。但是如果现在要写一个大型项目一下子写了很多源文件在编译它时岂不是要重复使用很多次gcc命令这样会不会太麻烦了或者如果不小心写错命令了岂不是更要命。所以在这里我们又要接触两样新事物make/Makefile.

make:是一个命令
Makefile/makefile:是一个文件(一般在当前源代码路径下)这里M大小写都可以

二.Makefile如何写入/make命令使用

如果要做一件事请我们首先要清楚两样事情依赖关系和依赖方法。比如你月底没钱花了要找妈妈要生活费打电话过去之后首先得喊一声妈吧这样才能让你妈知道电话那头是自己的孩子这就搞清楚了依赖关系。喊完妈之后再给自己母亲说明打电话的原因然后你妈打钱给你这个流程就是依赖方法。这两样事情都做正确了你才能从你妈那里要到生活费。

同样你如果需要Makefile文件和make指令帮你完成一项任务你首先要让它知道这个任务所需要的依赖关系和依赖方法。
知道这些东西后我们就开始用make命令来帮我们执行一次简单的任务–编译我们的.c源文件。

  1. 首先我们需要在Makefile内写一些指令
    在这里插入图片描述

  2. 接下来退出之后用make命令
    在这里插入图片描述
    直接make一下就自动去寻找Makefile文件然后就生成了myfile的可执行文件。方法很简单但是Makefile里面写的是啥还不清楚。接下来主要讲讲如何编写Makefile里面的内容。

2.1清楚依赖关系和依赖方法

编写Makefile的过程就是编写依赖关系和依赖方法的过程。我们最终要依靠myfile.c这个文件得到可执行文件myfile。所以这里的依赖关系就是myfile这个可执行文件要依赖myfile.c形成
所以Makefile第一行就写

//中间用:隔开
myfile:myfile.c

这行代码冒号左边的我们称为目标文件右边的称为依赖文件列表(右边可以有很多文件中间用空格隔开)

随后我们要清楚依赖方法就是如何用myfile.c文件生成myfile这个程序所以第二行要这样写

	gcc -o myfile myfile.c

注意第二行一定要用两个空格隔开。不要问为啥语法规定就是要这样写。

写完之后保存退出在用make指令执行就可以了。为了让大家更好的理解依赖关系和依赖方法这两个概念我将代码写的更细一点

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

make指令在执行这个文件时会先看第一行可执行文件要依赖.o的汇编文件生成但是此时还没有这个.o文件所以程序会继续向下寻找.o文件要依靠.s文件来生成但是.s文件也同样没有所以继续向下寻找…最后.i文件要依靠.c文件来生成。现在我们刚好有一个.c文件所以会开始执行下面的gcc指令从而生成了.i文件。有了.i文件程序会一步一步回去逐步生成.s.o可执行文件。这很像函数递归的样子。你也可以理解为这是数据结构里的栈上面的依赖关系是入栈下面的依赖方法是出栈

在这里插入图片描述

直接make命令执行就可以得到四个文件。

2.2删除文件

依赖关系中依赖文件列表可以没有没有的话也同样会执行下面的依赖方法。

所以如果要写一个删除文件的代码可以这样写

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

既然能学到这里我相信一个简单的删除指令就不用我多说了吧~。下面的这个rm指令就相当于依赖方法。

接下来我们就可以用make指令来执行这个程序了
在这里插入图片描述

因为make默认会执行第一组依赖方法和依赖关系所以这里在make后面加上需要的目标文件也就是clean目的就是让执行clean这一组依赖关系和依赖方法。

然后就可以发现我们这个目录下的四个文件的确被删除掉了。

2.3Makefile中的关键字.PHONY

我们刚刚已经可以用Makefile来帮助我们编译自己的程序或者删除文件。但是现在还有些缺陷就是你用make命令只能执行一次像这样
在这里插入图片描述

第一次时可以正常运行但是第二次的时候会说myfile这个文件已经是最新的了不让你在执行命令了。我们将这种现象称为不是总是被执行的。俗一点的说这个目标文件只能执行一次不让你一直执行。

如果现在希望让他每次make都能运行成功的话就再加一条命令

.PHONY:myfile
myfile:myfile.c
  gcc -o myfile myfile.c

在这里我们如果希望myfile这个目标文件总是被执行所以前面添加上这样一个关键字。
我们将.PHONY后面跟的文件叫做伪文件

现在发现一直重复执行make也能成功了
在这里插入图片描述

但是一般在编译的时候不建议这样写一般把这个编译器放在删除命令那边向下面这样写

myfile:myfile.c
  gcc -o myfile myfile.c

.PHONY:clean
clean:
  rm -f myfile 

在平时可能看不出来在一些大型项目编译的时候是很花时间的所以不推荐将编译生成可执行程序这一块加上,PHONY这个关键字。但是删除就不一样了你想删一次或多次都没啥影响的。(其实不加这个关键字你一直删也没啥问题)

2.4一个小补充

刚在我们看到如果没有.PHONY这个关键词修饰的话可执行程序只能被make命令执行一次但是make命令是怎么知道我们这个可执行程序是最新的呢
因为在系统中我们可以想象出有两条时间线(源代码和可执行程序)

在这里插入图片描述

首先源文件写完后的时间肯定要早于可执行程序运行的时间
在这里插入图片描述

make指令就会判断可执行程序运行后的程序是否晚于源文件运行的时间如果是就说明这个可执行程序是最新的。如果你修改过了这个源文件那可执行程序的时间就要晚于源文件的时间此时你在编译源文件make就会帮你去完成了。

make指令我们可以稍微“欺骗”一下。可以用touch这个指令。touch指令是如果后面跟的那个文件不存在就会帮你生成一个新的文件如果后面这个文件存在就会帮你更新这个文件的时间为最新时间。
在这里插入图片描述

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6
标签: linux