06makefile学习之三个自动变量(
@
,
@,
@,^,$<)和模式规则
以下为相关makefile的学习文章
01makefile学习之GCC编译的四个阶段(带编译阶段、汇编阶段、-S,-c的区别)
02makefile学习之makefile的基本原则
03makefile学习之makefile的一个规则
04makefile学习之多个规则处理多个文件
05makefile学习之两个函数和一个特殊规则clean
06makefile学习之三个自动变量(@ , @,@,^,$<)和模式规则
07makefile学习之习题1
08makefile学习之习题2
注:%表示代表一个或者多个字符。
1 三个自动变量
1)
@
:
表
示
规
则
的
目
标
,
并
且
只
能
出
现
在
命
令
中
,
不
能
出
现
在
规
则
第
一
行
中
。
2
)
@:表示规则的目标,并且只能出现在命令中,不能出现在规则第一行中。 2)
@:表示规则的目标,并且只能出现在命令中,不能出现在规则第一行中。2)^:表示规则的所有依赖条件,用列表存储,若有重复则删除重复。
3)$<:表示规则的一个依赖条件。若改变量应用在模式规则中,它的值将为依次从列表取出的值。
例如:
解释1):
hello:$(obj) //不能将hello改成$@,因为只能出现在下面的命令行中。
gcc $(obj) -o hello
对上一篇的makefile引入三个自动变量后如下(对比上一篇的makefile):
上一篇makefile:
src = $(wildcard ./*.c)
obj = $(patsubst %.c,%.o,$(src))
ALL:hello
hello:$(obj)
gcc $(obj) -o hello
hello.o:hello.c
gcc -c hello.c -o hello.o
add.o:add.c
gcc -c add.c -o add.o
sub.o:sub.c
gcc -c sub.c -o sub.o
mul.o:mul.c
gcc -c mul.c -o mul.o
clean:
-rm -rf $(obj)
添加自动变量后:
src = $(wildcard ./*.c)
obj = $(patsubst %.c,%.o,$(src)) #param bewteen is ","
ALL:hello
hello:$(obj) #终极目标一般不需要替换,下面的中间目标可以替换;$(obj)可以使用$^代替,但最好不要
gcc $(obj) -o $@ #"$@"只能用在命令行
hello.o:hello.c
gcc -c $< -o $@
add.o:add.c
gcc -c $< -o $@
sub.o:sub.c
gcc -c $< -o $@
mul.o:mul.c
gcc -c $< -o $@
clean:
-rm -rf $(obj)
看到上面,除了第一组规则是完全符合当前路径的文件增加能自适应,其它都还不行,怎么看呢?因为这些规则的第一行的目标和依赖都是固定文件名。
例如增加aa.c,必须增加一组规则,其它规则不能帮他自动增加。
2 使用模式规则,解决当前路径增加文件后,makefile能自动适应编译
模式规则:多组规则使用同一命令生成目标文件。
添加三个自动变量后我们仔细观察可以发现那四组规则的规律,如下:
hello.o:hello.c
gcc -c $< -o $@
add.o:add.c
gcc -c $< -o $@
sub.o:sub.c
gcc -c $< -o $@
mul.o:mul.c
gcc -c $< -o $@
它们都是用同一命令将.c文件生成.o文件,也就是说它们的模式规则为以下命令:
%.o:%.c //%表示代表一个或者多个字符
gcc -c $< -o $@ //注意,"$<"的值会变,为依次从$(obj)列表取出的值。
所以增加模式规则后的makefile文件为:
src = $(wildcard ./*.c)
obj = $(patsubst %.c,%.o,$(src)) #param bewteen is ","
ALL:hello
hello:$(obj)
gcc $(obj) -o $@
%.o:%.c
gcc -c $< -o $@
clean:
-rm -rf $(obj)
3 静态模式规则
其实上面的makefile也算是可以使用的makefile了,这里讲静态模式规则是使它更为完整。
静态模式规则:指定当前makefile使用哪一种模式规则。格式是只需要在模式规则的那组规则的第一行中添加$(obj)和冒号即可。
例如下面有两种(组)模式规则:
%.o:%.c
gcc -c $< -o $@
%.o:%.s
gcc -c $< -o $@
当我在当前目录增加一个div.c时,由于存在多组模式规则,makefile是无法分清要使用哪一种的,即使我们知道后缀是.c,但是makefile不知道啊,所以我们需要静态模式规则来指定使用哪一种模式。
添加静态模式规则:
$(obj):%.o:%.c //指定使用该组模式规则
gcc -c $< -o $@
%.o:%.s
gcc -c $< -o $@
所以添加静态模式规则的makefile写法为:
src = $(wildcard ./*.c)
obj = $(patsubst %.c,%.o,$(src)) #param bewteen is ","
ALL:hello
hello:$(obj)
gcc $(obj) -o $@
$(obj):%.o:%.c
gcc -c $< -o $@
clean:
-rm -rf $(obj)
4 额外增加调试信息和警告信息
非常简单,只需要定义一个变量,将选项值赋给它即可。
例如
debug = -Wall -g
所以从01篇到06本篇完整的makefile写法为:
src = $(wildcard ./*.c)
obj = $(patsubst %.c,%.o,$(src)) #param bewteen is ","
debug = -Wall -g
ALL:hello
hello:$(obj)
gcc $(obj) -o $@
$(obj):%.o:%.c
gcc -c $< -o $@ $(debug)
clean:
-rm -rf $(obj)
注意,因为我们只需要检查语法和调试信息,所以只需要在-c中添加即可,链接不需要。
好了,makefile的学习到此结束。