【Linux】-----工具篇(自动化构建工具make/makefile)

目录

前言

一、是什么? 

二、怎么样的? 

三、原理及细节

图解代码

细节1:make工作规则

 ①依赖文件存在

②依赖文件不存在

③依赖文件列表为空(特殊)

.PHONY关键字

细节2:makefile识别程序需要重新编译?

四、常用makefile写法 

①内置符号法

② 变量替换法


前言

前面在认识gcc/g++中我们知道,编译代码并形成可执行程序的指令为:gcc xxx.c -o xxx 。但是呢这样对于少量源文件来说还好,可是对于一个真正的工程项目,源文件是不计其数的,一个一个的编译未免有些许麻烦,有没有什么更加快速的方法呢?肯定有,不然我也不会写这篇文章的,对吧?来看看今天的主角make与makefile,用完你会爱上的!!

一、是什么? 

  • make就是单纯的一个命令,是一个解释makefile中指令的命令工具。。
  • makefile就是一个单纯的文件,但是内容一旦写好,只需要make命令,整个工程完全自动化编译,可以大大提高开发的效率!!
  • make和makefile搭配使用以完成项目的自动化构建。。

二、怎么样的? 

 看看实例代码:

先创建一个简单的C代码如下:

建一个简单makefile文件,如下

完成编译工作

可以看到,只需要一个make命令就能完成编译工作并形成可执行程序。。这就不需要每次编译源文件的时候都输入gcc xxx.c -o xxx这样一长串指令,效率提高了很多!

完成清理工作

可见,make会根据makefile的内容,完成编译/清理操作!!十分的nice!

大家估计会有疑问为什么编译工作仅仅用make一条命令,而清理用make clean?接着往下看!

三、原理及细节

图解代码

  • 依赖文件列表

可以同时存在多个源文件,以空格为分隔符,如:test.c test1.c .......

还可以为空,比如下面的清理操作,clean:,这是一种特殊的依赖关系!

  • 依赖关系

目标文件的形成依赖于后面文件列表,这就构成了依赖关系。如上述的test.exe:test.c,clean:  。(特殊)

  • 依赖方法

目标文件形成的所依赖的方法,也就是光有依赖关系还不够,还得需要对应的方法才能实现。。如上述的gcc以及rm操作就是依赖方法。。

此时上述的过程可以这样理解,使用make命令时,会在当前目录下寻找makefile文件,读取里面的内容,并根据依赖关系去找到对应的依赖方法并执行生成对应的目标文件!!

细节1:make工作规则

默认情况下,单单使用make命令是从上往下读取文件的, 默认执行第一对依赖关系和依赖方法,其他的不管,形成的是第一个目标文件!

 ①依赖文件存在

先看演示:

当前目录下的文件:

makefile文件内容:

make一下看结果:

会发现此时执行顺序是从下往上的,不是说仅仅使用make命令时,从上往下读,只会执行第一对依赖关系吗?

        是的没错,还是从上往下读,执行第一对依赖关系,但是因为第一对依赖关系中的依赖文件test.o并不存在于当前目录,那么此时make会在当前文件中找目标文件为test.o的依赖关系,发现依赖文件test.s也并不存在,以此类推,最后推导发现依赖文件test.c存在,就执行对应的依赖方法,在从下往上。如果推导至最后发现还是没有文件,那么此时的make就会直接退出,并报错!!

②依赖文件不存在

注意:这种情况下的不存在不是为空哦

演示:

当前目录下的文件:

makefile中的内容:

code.c文件并不在该目录下,来看结果:

可见,当依赖文件不存在时,make就不工作了!!!!!

依赖文件列表为空(特殊)

看演示:

将上述的clean操作放在test.exe前面

看结果:

从上往下读取,但是碰到依赖文件为空时,会直接执行对应的依赖方法。。不会再向下推导了。。也就是make将这种情况也视为依赖文件存在的情况。。

那么此时如果要执行生成其他的目标文件,那就需要带上对应目标文件的名称!

所以,我们一般习惯上把形成可执行程序的目标文件放在第一位,文件的清理工作放在其他的位置,这也是开头演示时为什么使用make clean命令的原因!

小总结: make会自动根据文件的依赖性,进行自动推导,帮助我们执行所有相关的依赖方法!!

.PHONY关键字

.PHONY:xxx

xxx对应的依赖方法,总是要被执行的!!!!

来看对比:

无该关键字时:

可以看到,只能make一下,当你连续make多次,是无法实现的!!因为makefile对最新生成的可执行程序,默认不会在重新生成,这样可以提高编译的效率!!除非你更新可执行程序所依赖的源文件时,才可以重新make!

但是可以加上.PHONY关键字就能打破这种限制!

如下图:

结果:

但是实际上对于生成可执行程序的,一般不用这个关键字去修饰,这样编译效率不高(对于一个大工程而言),默认情况都是用于修饰clean这样的项目清理文件。。让清理工作总是被执行!

细节2:makefile识别程序需要重新编译?

实际上就是对比源代码和可执行程序最近一次形成或修改时间,谁是最新的

  • 如果源文件是最新的,说明刚完成更改,需重新编译!!允许make!
  • 可执行程序是最新,说明不需要重新编译,不允许make!!

先有的源文件,编译才能形成可执行程序!所以源文件和可执行程序形成和修改的时间一定不一样,除非特意修改!!

这就是为什么不能连续make的原因!!

但是有一点要注意:

对于那些没有依赖文件的目标文件,就没有这种限制!!比如上述的clean清理工作,它就可以无限make,爱咋咋地!

四、常用makefile写法 

 对于上面的依赖方法的写法还是有点麻烦,还是要写gcc xxx.c -o xxx。(小文件还行)来看以下两种写法。

①内置符号法

$^:代表依赖文件

$@:代表目标文件

执行结果也是一样:

注意:对于清理文件不能用内置符号。

② 变量替换法

 

执行结果:

这东西和宏类似,只需要改变上面变量的值就可以了,很方便!!

补充:

每次我们在make时,都会有gcc……这条指令显示出来,如果不想显示,可以这样改

在依赖方法前加上@符号即可。


好了,兄弟们,今天的分享就到这里,如果觉得对你有所帮助,欢迎点赞+关注+收藏!!

  • 21
    点赞
  • 23
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值