浅讲make/makefile【linux】

一. 什么是make/makefile?

make/makefile这两个可以说是搭档,缺一不可
make和makefile可以说是做大型项目不可缺少的功能
就本质来讲
make是系统自带的一条指令
makefile则是一个文件

使用make后:
编译器会自己去寻找目录下的makefile文件并执行

可以说make的指令作用:就是执行本目录下的makefile文件
当目录下没有makefile文件的时候就会报错
在这里插入图片描述

所以我们在学习make/makefile的功能,主要专注在makefile内部

二. makefile

想用make/makefile功能,直接自己在本目录下创建个makefile文件即可

touch makefile

在这里插入图片描述
用vim编辑器进行修改。
在这里插入图片描述
发现文件内是全空的,所以我们想要写出能用的makefile文件,需要先了解依赖关系与依赖方法

2.1 依赖关系与依赖方法

在这里插入图片描述
这里一条最普通的编译test的makefile指令

让我们看看这两行分别是什么

在这里插入图片描述
这里我们能看到一个指令的组成有两个部分

1.依赖关系
2.依赖方法

接下来我们分别来看一下这两个部分:

依赖关系:
在这里插入图片描述
左边可以说是指令名。
使用的时候就是
make test 来执行

test.cpp是test指令依赖的文件。

依赖方法
在这里插入图片描述
依赖方法可以说是
编程语言中函数体内的函数内容。
就是执行的指令

2.2 浅用make

了解了具体了以后我们就可以试着来编写两个makefile的文件了

2.2.1 make test

在这里插入图片描述
这个就是我们上面的例子,接下来我们来使用一下。
在这里插入图片描述
这里随便写了一个test.cpp的文件
在这里插入图片描述
这里输入

make test

可以发现这里已经执行了。
在这里插入图片描述
发现已经多了个可执行程序,makefile指令已经执行完毕了

2.2.2 clean

相同的,我们也可以写个像C++中的析构函数那样的清理可执行程序的clean指令

clean:
        rm -rf test

依赖关系冒号后面没有跟文件,代表这个指令没有依赖文件

这里来执行一下

make clean

在这里插入图片描述
发现test可执行程序被删除了

2.2 make一次执行多步

讲这个内容时会涉及到语言的执行过程,如果看不太懂,可以去翻我以前的博客
C语言程序的编译过程

在这里插入图片描述

这里的test.i ,test.s,test.o
都是之前程序编译和汇编以及链接的生成文件。

这里如果直接用make test.i会怎么样?
这不是很简单嘛
直接执行

g++ test.cpp -o test.i -E

就结束了。

但是如果我们执行 make test会怎么样?

在这里插入图片描述

我们会发现一下执行了全部的指令。

这里让我们来刨析一下过程。

在这里插入图片描述
第一步执行test时,发现依赖关系时test.o文件,但是系统查找不到
这是时候就会去寻找具有test.o的命令
在这里插入图片描述

这个时候找到 test.o指令,但是发现执行需要test.s,这个时候又会去寻找test.s文件

在这里插入图片描述

就这样不停寻找,找到了test.i能进行创建了
在这里插入图片描述

这个时候在返回到上一条需要test.i的指令,并执行
就这样一条一条执行并返回,就类似于递归一样的思路

那我们如果随便换个顺序也是结果会怎么样
在这里插入图片描述

在这里插入图片描述

发现结果不会变,因为顺序不会影响执行
系统是会寻找可以执行的指令,自动去执行,如果没有就报错
就C语言中的函数一样,引用函数不需要注重顺序,只要能被系统找到就可以了

2.3 部分修饰符号

接下来是几个比较基础的修饰符号

2.3.1 .PHONY(伪目标)

在执行makefile时,如果可执行文件已经产生,为了防止重复无意义的执行生成可执行文件指令
会自动判断可执行文件的源文件是否发生变动,从而判断是否要执行编译

例:在这里插入图片描述
这里进行了第一次编译。
在这里插入图片描述
第二次执行的时候就会发现,系统会阻止你重复make

那这么高大上的功能是怎么实现的呢?

其实就是通过对比时间而已

我们可以通过

stat 【文件名】

查看文件属性
在这里插入图片描述
access:访问时间
对文件内容进行修改:modify
对文件属性进行改变:change

这里要注意:对文件属性进行修改,文件内容的时间一般也会修改
因为文件内容有一个size的属性

按道理来说,对文件执行指令,access时间都要进行改变
但是因为access变化实在是太过于频繁,文件处于磁盘中,多个用户访问文件都要改变access,导致服务器十分卡顿
所以较新版中,只有对文件进行一定量的操作后才能会进行改变access时间

所以make文件对源文件进行依赖关系的操作的时候
会将可执行程序的时间转化为时间戳,将.cpp文件的修改时间转化为时间戳
进行比较,判断是否要执行指令

这里如果想要取消时间戳对比
就可以添加.PHONY修饰(伪目标)
但是不推荐将生成可执行文件用伪目标进行修饰
在这里插入图片描述
在这里插入图片描述
这里就可以随便进行执行了,不用进行时间戳的对比。

2.3.2 @

我们在输入了make后
make会自动弹出makefile中执行指令的依赖方法
在这里插入图片描述

在这里插入图片描述


加了@后,就可以防止弹出依赖方法

2.3.3 $@ $^

这两个修饰符主要用在依赖关系上

在这里插入图片描述
这两个分别代表了依赖关系的两边

那具体有什么用呢?

在这里插入图片描述
写依赖方法的时候就可以用符号代替文件名了

在这里插入图片描述
这里能发现文件正常执行了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

想学c啊啊

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

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

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

打赏作者

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

抵扣说明:

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

余额充值