MakeFile的使用

前言:

在前边的文章中我们提到了GCC编译器如何去使用,但是在编译的时候都是一条的指令对已知的文件进行编译,但是对于工程文件数目较大的项目,如果修改了多个文件就需要对多个文件进行预编译、编译、汇编、链接,需要执行多条gcc命令尤其麻烦,这里引出makefile文件帮助我们轻松的组织代码编译,可以将多条编译命令转换为一条命令

Makefile编译过程:

Makefile文件中的命令有一定的规范,一旦该文件编写好以后在Linux命令中执行一条make命令即可自动编译整个工程。

Makefile语法规则

规则:

我的这边博客意在会用会看,对一些深入的内容请参考下边分享的Makefile中文文档

链接: https://pan.baidu.com/s/1vz2PD-NhZ8zYF5qfCX2V8A?pwd=crw8 提取码: crw8 

目标:依赖
    命令1
    命令2
    …………

Makefile并不关心命令是怎么命令是怎么执行的,仅仅只会去执行所有定义的命令,命令的执行仍是编译器进行的,和直接输入命令行的效果是一样的。

  1. 目标是要生成的文件,如果目标文件的更新晚于依赖文件的更新时间,则说明依赖文件没有进行改动,目标文件不需要重新编译。否则会进行重新编译并且更新目标文件。
  2. 默认情况下,Makefile执行第一个目标
  3. 依赖:即目标文件由哪些文件组成。
  4. 命令:通过执行命令有依赖文件生成目标文件。注意每条命令之前都必须有一个tab保持缩进,这是语法要求。
  5. all:Makefile文件默认只生产第一个目标文件即编译完成。但是我们可以通过all指定索要生成的目标文件

实验1:第一个Makefile文件

将下述三个命令写成简单的Makefile

如果文件

编译:

gcc -o a.o a.c

gcc -o b.o b.c

链接:

gcc -o test a.o b.o

文件:Makefile   

test :a.o b.o //test是目标,它依赖于a.o b.o文件,一旦a.o或者b.o比test新的时候, 就需要执行下面的命令,重新生成test可执行程序。

        gcc -o test a.o b.o

a.o : a.c //a.o依赖于a.c,当a.c更加新的话,执行下面的命令来生成a.o

        gcc -c -o a.o a.c

b.o : b.c //b.o依赖于b.c,当b.c更加新的话,执行下面的命令,来生成b.o

        gcc -c -o b.o b.c

执行效果:

a.c文件修改了,重新编译生成a.o, b.c修改了重新编译生成b.o,a.o,b.o都更新了重新链接生成test可执 行程序,makefile的规则其实还是比较简单的。规则是Makefie的核心, 执行make命令的时候,就会在当前目录下面找到名字为:Makefile的文件,根据里面的内容来执行里 面的判断/命令。

通配符:

假如一个目标文件所依赖的依赖文件很多,那样岂不是我们对应的要写很多规则,这个显然不符合道理。于是有了通配符。

可以对上边的Makefile中的代码改写成

test: a.o b.o

        gcc -o test $^

%.o : %.c

        gcc -c -o $@ $<

%.o:表示所用的.o文件

%.c:表示所有的.c文件

$@:表示目标

$<:表示第1个依赖文件

$^:表示所有依赖文件

加一个类似的c.c文件

执行效果:

假想目标:.PHONY

我们想清除文件,我们在Makefile的结尾添加如下代码就可以了:

clean:
	rm *.o test
.PHONY: 
	clean 

我们之前说,一个规则能过执行的条件:

*1)目标文件不存在

*2)依赖文件比目标新

现在我们的目录里面有名为“clean”的文件,目标文件是有的,并且没有依赖文件,没有办法判断依赖文件的时间。这种写法会导致:有同名的"clean"文件时,就没有办法执行 make clean操作。解决办法:我们需要把目标定义为假象目标,用关键子PHONY

.PHONY: clean //把clean定义为假象目标。他就不会判断名为“clean”的文件是否存在,

执行效果:

变量:

在makefile中有两个变量:

1、简单变量(即使变量)

A := xxx # A的值即刻确定,在定义时即确定

对于即使变量使用 “:=” 表示,它的值在定义的时候已经被确定了

2、延时变量

B = xxx # B的值使用到时才确定 对于延时变量使用“=”表示。它只有在使用到的时候才确定,在定义/等于时并没有确定下来。

变量的使用:

使用$()进行引用,例如:$(A)

:= # 即时变量

= # 延时变量

?= # 延时变量, 如果是第1次定义才起效, 如果在前面该变量已定义则忽略这句

\+= # 附加, 它是即时变量还是延时变量取决于前面的定义

?=: 如果这个变量在前面已经被定义了,这句话就会不会起效果。

实例:

效果显示:

1) A := $(C): A为即使变量,在定义时即确定,由于刚开始C的值为空,所以A的值也为空。 2) B = $(C): B为延时变量,只有使用到时它的值才确定,当执行make时,会解析Makefile里面的所用变量,所以先 解析C= abc,然后解析C += 123,此时,C = abc 123,当执行:\@echo B = $(B) B的值为 abc 123。

3) D ?= weidongshan: D变量在前面没有定义,所以D的值为weidongshan,如果在前面添加D = 100ask,最后D的值为 100ask。

我们还可以通过命令行存入变量的值

例如: 执行:make D=123456 里面的 D ?= weidongshan 这句话就不起作用了。

函数:

makefile里面可以包含很多函数,这些函数都是make本身实现的,下面列出我们来几个常用的函数。其他函数有需要的直接去查文档即可

foreach函数

举个例子来说:

A = a b c
B = $(foreach f,$(A),$(f).o)


all:
	@echo A = $(A)
	@echo B = $(B)

效果显示:

我理解的就是把LIST中的以空格分割的元素,放到分别放到VAR中,然后在拓展成TEXT格式

filter/filter-out函数

Wildcard函数

可以用wildcard函数来判断,真实存在的文件

patsubst函数

patsubst 函数是从TEXT变量里面取出每一个值,如果这个符合 pattern 格式,把它替换成 replacement 格式,

实例:

Makefile实例

这里就参考韦东山老师对Makefile实例的讲解把,我感觉非常棒,在我绑定的资源里边

  • 21
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值