跟我一起学Makefile

什么是makefile呢?makefile是用来指定编译的规则的一个文本,当你在开发一整个项目的时候,例如当你使用gcc main.c hello.c -o main.o 当使用这样的命令的时候,gcc编译器会自动去把main.c和hello.c一起进行编译,但是如果需要编译的文件越来越多,那么使用这种命令是非常不方便的,而makefile就解决了这种问题,当然后续我们还会学习更加现代的项目管理工具CMAKE。

MakeFile的安装

sudo apt install -y build-essential

MakeFile内容通常由以下3部分组成

<目标名称>:<前置依赖>
	需要执行的命令	
例如
main:hello main.o
	gcc hello.o main.o -o main

下面,我们在基础的makefile文件上进行扩展

main:main.o hello.o
	gcc main.o hello.o -o main
main.o:main.c hello.h
	gcc -c main.c
hello.o:hello.c hello.h
	gcc -c hello.c
clear:
	rm main main.o hello.o

其中,由于main.o依赖main.c和hello.h文件,因此需要都加上,hello.o同理。gcc -c参数是用来生成.o文件的参数
clear是配置,当执行make clear命令的时候,可以一键清除main,main.o,hello.o文件。
当我们在makefile文件所在的目录的终端中执行命令make的时候,编译器就会自动执行make中的编译规则。
在这里插入图片描述
在这里插入图片描述

变量

在makefile 中我们也是有变量的,为什么要有变量呢?在上面我们的makefile示例中,可以看到我们在多处使用了main.o hello.o,因此,我们可以用一个变量等于这两个东西,然后在使用这两个文件的地方用变量名进行替换即可

object:=main.o hello.o
main:$(object)
	gcc $(object) -o main
main.o:main.c hello.h
	gcc -c main.c

hello.o:hello.c hello.h
	gcc -c hello.c
clear:
	rm main $(object)

可以看到,我们定义的时候是变量名:=值的形式定义,使用的时候是$(变量名)这种形式来使用
在这里插入图片描述
makefile中还有三个默认的变量,我们可以直接使用
$@:表示目标文件。
$^:表示所有的依赖文件。
$<:表示第一个依赖文件。

自动推导功能

在makefile中,是有自动推导功能的,这个功能是什么意思呢?就是说我们完全可以只写

object:=main.o hello.o
main:$(object)
	gcc $(object) -o main
clear:
	rm main $(object)

这一部分,而对于main.o和hello.o,makefile会想方设法的去给你编译出来,因此无需我们自己去设置规则,这样一来我们的makefile文件就大大简化了,但是这样会导致一个问题,当我们使用自动推导main.o和hello.o的时候,其实自动推导是不去管.h文件的,因此这样就会让makefile没法检测.h文件的变化,因此我们需要加上.h文件,整理后的makefile文件内容如下:

object:=main.o hello.o
main:$(object)
	gcc $(object) -o main
main.o:hello.h
hello.o:hello.h
clear:
	rm main $(object)

在这里插入图片描述
小tips:打开vscode中的终端快捷键是"ctrl+反引号"

伪目标

伪目标并不代表实际的文件名,它更多地是行为或者动作的标识符,伪目标并不生成具体文件。
例如我们在上面代码中的clear,这就是一个伪目标,因为我们并没有生成一个叫做clear的目标文件,而仅仅是当我们使用make clear的时候会执行特定的命令。
当我们在makefile中使用当前文件夹下没有的文件名称的时候,它默认就是一个伪目标,那么什么情况下我们会使用到伪目标呢?当我们文件夹下有一个叫做clear的文件,他的名字与clear产生了冲突,此时我们就需要显示的声明以下clear是一个伪目标。
声明伪目标的语法是:

.PHONY:<伪目标名称>
例如:
.PHONY:<clear>

在这里插入图片描述
假若我们没有这个显示声明,而且还有同名文件,他的执行情况就会如下图所示
在这里插入图片描述

禁止报错

当我们重复执行make clear的时候,会产生一些报错信息,那么,我们如果不想看到这些报错信息,就可以在rm main $(object)前面加一个-,因此完整的命令就是-rm main &(object)
在这里插入图片描述

问题

对于

main:main.o hello.o
	gcc main.c hello.c -o main123

当我们gcc的生成文件名称叫做main123,而另一个目标文件叫做main的时候,会发生什么呢?我们会发现生成的文件名称叫做main123,那么我们可不可以这样做呢?这样做是不可以的,我们要时刻保证main与main123名称相同,这是因为main是我们makefile要监视的文件,而main123是生成的文件,这俩名称不匹配就会造成监视不到生成的文件,因此会造成重复编译。

以上就是makefile的全部内容,当然这只是基础的学习内容,但是对于我们学习嵌入式Linux应用开发已经足够了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值