点击蓝字

关注我们

    在前一篇文章讲解了Makefile的一些概念和原理,接下来说说Makefile的一些知识点。

eed3f99d96efec2c671e5fb487d494a4.pngmake与make cleaneed3f99d96efec2c671e5fb487d494a4.png

生成目标文件规则(make命令):

执行make命令则会根据当前目录的Makefile文件定义的规则生成对应的目标文件。

如果Makefile为其他名字,比如makefile.linux,则需要使用make的参数(-f or –file)执行对应的Makefile文件,例如:

make -f makefile.linux

清空目标文件的规则(make clean命令):

每个Makefile中都应该写一个清空目标文件(
.o 和目标文件等)的规则,这不仅便于重编译,也很 利于保持文件的清洁。也许在写Makefile的时候,都要养成这样一个习惯,一般的风格都是:

clean:    rm $(obj) *.o

 更为稳健的做法是(原因:如果当前目录存在clean文件,该命令会执行失败),解决办法:增加伪目标:.PHONY:clean:

.PHONY:cleanclean:    rm $(obj) *.o

注意:

  • clean的规则不要放在文件 的开头,不然,会变成make的默认目标,一般:clean从来都是放 在文件的最后。

2f12c57063ff4d324164b3d18689b509.png书写规则2f12c57063ff4d324164b3d18689b509.png

显示规则(@字符):

当用@字符在命令前面时,那么执行这条命令的时候,这条命令不会显示出来。对比:
命令前加@字符例子:

rice@rice:~/rice_file/mkfile$ cat Makefile exec:  @echo "rice makefile"rice@rice:~/rice_file/mkfile$ makerice makefile

命令前不加@字符例子:

rice@rice:~/rice_file/mkfile$ cat Makefile exec:  echo "rice makefile"rice@rice:~/rice_file/mkfile$ makeecho "rice makefile"rice makefile

注意:

make命令参数
-s
--silent
--quiet 则是全面禁止命令的显示

命令执行规则:

当依赖目标新于目标时,make会一条一条的执行其后的命令。其中,加入要让上一条命令的结果应用在下一条命令时,应使用
分号分隔这两条命令,并且不能将两条命令写在
同一行。

例子1:

Makefile:

exec:    @cd /home/rice    @pwd

结果:

/home/rice/rice_file/mkfile

例子2:

Makefile:

exec:    @cd /home/rice;pwd

结果:

/home/rice

从上面两个例子可以证明命令依赖的规则。

命令出错规则(-符号):

当命令运行完,make会检测每个命令的返回码,如果返回成功,那make会执行下一条命令,当规所有的命令成功返回后,make执行完成。如果一个规则中的某个命令出错了(命令退出码 非零),那么make就会终止执行当前规则,这将有可能终止所有规则的执行。

有时命令的出错并不表示错误。例如mkdir命令,建立一个目录,如果目录不存 在,则mkdir不会出现错误。如果目录已存在,那么将产生错误。从例子说明,mkdir的出错并没有对其他命令产生影响,因为我只要目录存,所以mkdir出错不应该终止命令规则的运行。

为了解决上述问题,只需要在Makefile的命令行前加一个符号
-,即使命令执行出错,也依然继续执行后续的命令。

.PHONY:cleanclean:    -rm $(obj) *.o

6164af61308393dfd0c54c7a59bd3b2a.png变量6164af61308393dfd0c54c7a59bd3b2a.png

变量的定义

Makefile
也支持变量定义,变量的定义也让的我们的Makefile
更加简化,可复用。
变量的定义:一般采用大写字母,赋值方式像C
语言的赋值方式一样。

DIR = ./src/


变量取值:使用括号将变量括起来再加美元符。

FOO = $(DIR)

Makefile
除了使用’=’
进行赋值,还有其他赋值方式,比如’:=’
和’?=’
,接下来我们来对比一下这几种的区别:

赋值符’=’:

PARA = RICECURPARA = $(PARA)PARA = riceprint:  @echo $(CURPATA)

结果为:

rice


变量CURPARA
的值并不是“RICE”
。其值为PARA
最后一次赋值的值。说明,赋值符“=”
,可以借助另外一个变量,
可以将变量的真实值推到后面去定义。也就是变量的真实值取决于它所引用的变量的最后一次有效值。

赋值符’:=’:

PARA = RICECURPARA := $(PARA)PARA = riceprint:  @echo $(CURPATA)

结果为:

RICE

变量CURPARA的值为“RICE”。“=”和“:=”的区别就在这里,“:=”只取第一次被赋值的值。

赋值符’?=’:

PARA = RICEPARA ?= riceprint:  @echo $(PATA)

结果为:

RICE

如果上面例子第一行去掉,结果为:

rice

说明,如果变量PARA
前面没有被赋值,那么此变量就是“rice”
,如果前面已经赋值过,那么就使用前面赋的值。
赋值符’
+=’:Makefile
中的变量是字符串,有时候我们需要给前面已经定义好的变量添加一些字符串进去,
此时就要使用到符号”+=”:

OBJ = main1.o main2.oOBJ += main3.o

OBJ
的值为:”main1.o
main2.o
main3.o“
。说明“+=”
用作与变量的追加。

系统自带变量:

系统自定义了一些变量,通常都是大学,比如CC
PWD
CLFAG
等等,有些有默认值,有些没有,比如以下几种,如下

  • CPPFLAGS:预处理器需要的选项,如:-l

  • CFLAGS:编译的时候使用的参数-Wall -g -c

  • LDFLAGS:链接库使用的选项-L -l

其中:默认值可以被修改,比如CC
默认值是cc
,但可以修改为gcc
CC=gcc

自动变量:

Makefile
的语法提供一些自动变量,这些变量可以让我们更加快速的完成Makefile
的编写,其中自动变量只能在规则中的命令使用,常用的自动变量如下:

  • $@:规则中的目标

  • $<:规则中的第一个依赖文件

  • $^:规则中的所有依赖文件

CC = gccOBJ = main.o add.ooutput: $(OBJ)  $(CC) -o $@ $^main.o: main.c  $(CC) -c $<add.o: add.c  $(CC) -c $<.PHONY:cleanclean:  @rm $(OBJ) output

017393dc02b6b0b7722d468aeb9c0000.png模式规则017393dc02b6b0b7722d468aeb9c0000.png

模式规则实在目标及依赖中使用%
来匹配对应的文件,我们依旧使用上面的例子,采用模式规则格式,如下:

CC = gccOBJ = main.o add.ooutput: $(OBJ)  $(CC) -o $@ $^%.o: %.c  $(CC) -c $<.PHONY:cleanclean:  @rm $(OBJ) output

其中:

main.o
main.c
生成 add.o
add.c
生成
d372498d7537106380064f3a9f41576b.png
函数
d372498d7537106380064f3a9f41576b.pngMakefile
提供了大量的函数,其中我们经常使用的函数主要有两个(wildcard
patsubst)。
wildcard
函数:用于查找指定目录下指定类型的文件,函数参数:目录+
文件类型,使用方法:

SRC = $(wildcard ./src/*.c)print:  @echo $(SRC)

结果:

./src/add.c ./src/main.c

表示:找到目录./src
下所有后缀为.c
的文件,并赋值给变量SRC
。命令执行完,SRC
变量的值:./src/add.c ./src/main.c

patsubst函数:用于匹配替换。函数参数:原模式+目标模式+文件列表,使用方法:

SRC = $(wildcard ./src/*.c)OBJ = $(patsubst %.c, %.o, $(SRC))print:  @echo $(OBJ)

结果:

./src/add.o ./src/main.o

表示:把变量中所有后缀为.c
的文件替换为.o
。命令执行完,OBJ
变量的值:./src/add.o ./src/main.o
038449d3fc61cd5dc684f21f0c70b689.gif
abaf64adcf952b37b5dc898093dc2232.gif
b7fb4036a89b26dba5d8ac5ba85fd259.gif

我将持续更新文章和学习资料

可加作者的微信一起交流学习

b7fb4036a89b26dba5d8ac5ba85fd259.gif

作者微信号:wueroo1314

获取交流群,请添加作者微信

饭仔DIY

微信号 : Rice_DIY

技术 | 开源 | 分享 

长按关注。。。

068864edc0fe07b748318f905c08d379.png