1、自动变量的使用
$@:用于表示一个规则中的目标。当一个规则中有多个目标时,$@所指的是其中任何造成规则命令被运行的目标。
$^:表示的是规则中的所有先决条件
$<:表示的是规则中的第一个先决条件
如下所示代码:
.PHONY:all
all: first second third
@echo "\$$@ = $@"
@echo "$$^ = $^"
@echo "$$< = $<"
first second third :
运行结果如下所示:
[root@test simple]# make
$@ = all
$^ = first second third
$< = first
[root@test simple]#
以上测试代码有几个地方需要注意:第一、在Makefile中“$”具有特殊的意思,如果想采用echo输出"$",则必须用两个连着的“$”;第二、"$@"对于Bash Shell也有特殊的意思,需要在“$$@”前加一个脱字符“\”
2、特殊变量
在Makefile中,有两个特殊变量会经常用到:MAKE和MAKECMDGOALS。MAKE变量表示当前的是当前处理Makefile的命令名是什么?一般$(MAKE)的值就是“make”。当需要在Makefile中运行另一个Makefile时,需要用到这个变量。
测试代码如下:
.PHONY:all
all:
@echo "MAKE = $(MAKE)"
MAKECMDGOALS变量表示的是当前构建的目标名。测试代码如下
.PHONY:all clean
all clean:
@echo "MAKE = $(MAKE)"
@echo "\$$@=$@"
@echo "MAKECMDGOALS = $(MAKECMDGOALS)"
[root@test simple]# make
MAKE = make
$@=all
MAKECMDGOALS =
[root@test simple]# make all
MAKE = make
$@=all
MAKECMDGOALS = all
[root@test simple]# make clean
MAKE = make
$@=clean
MAKECMDGOALS = clean
3、变量的类别与赋值
变量的类别有递归变量和简单扩展变量。 只用一个“=”符号定义的变量被称为递归变量(recursively expanded variable),递归变量的引用是递归的。如下测试代码所示,这点和C语言有点区别,C语言中的变量只能是定义了过后才能使用
CFLAGS = $(include_dirs) -o
include_dirs = -Ifoo -Ibar
all:
@echo $(CFLAGS)
简单扩展变量(simply expanded variable)是用“:=”操作符来定义的。对于这类变量,make只对其进行一次展开。测试代码如下
x = foo
y = $(x) b
x = later
xx := foo
yy := $(xx) b
xx := later
test:
@echo "x=$(y) xx = $(yy)"
从以上测试可以发,递归扩展可以对变量进行多次展开,而简单扩展只进行一次展开。
除了以上两种赋值方式,在Makefile中还有条件赋值、追加赋值等等
条件赋值(“?=”):当变量没有被定义时就定义它,并且将右边的值赋给它;如果变量已经定义了,则不改变其原值。条件赋值可用于为变量付默认值
追加赋值(“+=”):在当前变量值基础上叠加上当前追加的值
4、变量及其值的来源
从前面学习可以发现,在Makefile中可以对变量进行定义。此外,还有其他的方式让make获取变量。比如:
对于自动变量,其值是在每一个规则中根据规则的上下文自动获取的;
在运行make命令时,通过命令参数定义变量;
变量还可以来自于Shell环境
5、高级变量的引用
在Makefile可以进行一种高级变量的引用,即在赋值的同时完成文件后缀替换操作。
foo = a.c b.c c.c
bar := $(foo:.c=.o)
all:
@echo $(bar)
此项用法,在后期的项目中应用是非常普遍的