一、通配符
① $@ 表示目标文件的名称
$@是一个自动变量,它代表当前目标文件的名称。当你编写一个规则来构建某个目标文件时,$@就会被替换为那个目标文件的名称。
例如,假设你有以下的Makefile规则:
test_utio:a.o b.o c.o
gcc a.o c.o -o $@
在这个例子中,当你运行时,gcc命令会执行,并且$@会被替换为test_utio。
② $< 表示第一个依赖文件
它代表依赖项列表中的第一个依赖项。当你在规则中编写命令时,$<会被替换为规则中依赖项列表中的第一个文件的名称。 例如
%.o : %.c
gcc $(CFLAGS) -c -o $@ $< -MD -MF .$@.d #编译所有的.c .o 文件并写入依赖
③ $^ 表示所有依赖文件
它代表所有依赖项的列表,每个依赖项之间以空格分隔。当你在规则中编写命令时,$^会被替换为规则中列出的所有依赖项。
test: $(objs)
gcc -o test $^ #将 objs 中的.o文件链接到 test 中
二、假想目标.PHONY
Make 使用时后面可以加上目标,make[目标],如 Make clean ,clean在makefile中实现,如果不加目标,会默认执行第一个,当使用make clean 时会将编译产生的.o文件,和链接产生的test文件删除,
例如下面这两行,在执行 make clean 指令后,会将变异产生的所有 .o 文件删除
clean:
rm *.o test
make后面可以带上目标名,也可以不带,如果不带目标名的话它就想生成第一个规则里面的第一个目标。
但是如果我们创建了一个clean文件时,再次使用make clean时会报错,这时,我们就需要在Makefile
文件中加入假想目标,如
三、即时变量、延时变量
简单变量(即时变量):
A := xxx #A的值立刻确定,在定义的时候就会立马起作用
B = xxx #B的值在使用到的时候才会起作用
如下面make时,会显示A空,B的值为123
A := $(D)
B = $(D)
D = 123
all:
@echo A = $(A)
@echo B = $(B)
此外还有
:= #即时变量
= #延时变量
?= #延时变量,在第一次定义时才起作用,如果在前面已经定义过那么可以忽略这个
+= #附加,即时变量还是延时变量取决与前面的定义
四、常用函数
① foreach函数,更改函数
原型:$(foreach var,list,text) 将list中的每个值,按照text对应的格式进行更改
在make中
A = a b c
#输出为a.o b.o c.o foreach为函数,对于 A 中的每个值,执行一下 f.o
B = $(foreach f, $(A), $(f).o)
#也可以是.c,就是用后面的代替前面的
BB = $(foreach f,$(A),$(f).c)
#也可以在前面加
CC = $(foreach f,$(A),a.$(f))
输出为![a6714a9dd2f1467ea14b263161c32bda.png](https://img-blog.csdnimg.cn/direct/a6714a9dd2f1467ea14b263161c32bda.png)
② filter/filter-out 选择函数
$(filter pattern...,text) # 在text中取出符合patten格式的值
$(filter-out pattern...,text) # 在text中取出不符合patten格式的值
③ Wildcard函数,查询函数
$(wildcard pattern) # pattern定义了文件名的格式, wildcard取出其中存在的文件。
④ patsubst函数
$(patsubst pattern,replacement,\$(var))
patsubst 函数是从 var 变量里面取出每一个值,如果这个符合 pattern 格式,把它替换成 replacement 格式,
五、gcc依赖
① Gcc -M c.c //打印出c.c的依赖
② Gcc -M -MF c.d c.c //把依赖写入c.d文件
③Gcc -c -o c.o c.c -MD -MF c.d//编译c.o,并把依赖写入c.d
六、综合小实例