1.变量基础
变量在声明时需要给予初值,而在使用时,需要给在变量名前加上“$”符号,但最好用小括号“()”
或是大括号“{}”把变量给包括起来。如果你要使用真实的“$”字符,那么你需要用“$$”来表示。
变量可以使用在许多地方,如规则中的“目标”、“依赖”、“命令”以及新的变量中。先看一个例子:
objects = program.o foo.o utils.o
program : $(objects)
cc -o program $(objects)
$(objects) : defs.h
变量会在使用它的地方精确地展开,就像 C/C++中的宏一样,例如:
foo = c
prog.o : prog.$(foo)
$(foo)$(foo) -$(foo) prog.$(foo)
展开后得到:
prog.o : prog.c
cc -c prog.c
2.变量中的变量
在定义变量的值时,我们可以使用其他变量来构造变量的值,在Makefile中有两种方式来使用变量定义变量的值。
第一种方式,也就是简单的使用"="号,在"="左侧是变量,右侧是变量的值,右侧变量的值可以定义在文件的任何地方,也就说,右侧的变量不一定非要是已定义好的值,也可是使用后面定义的值。如:
foo=$(bar)
bar=$(ugh)
ugh=Huh?
all:
echo $(foo)
当我们执行make all会打印变量$(foo)的值:Huh?
可见,便是是可以使用后定义的。
这个功能有好的地方,也有不好的地方,好的地方是,我们可以把变量的真实值推到后面来定义,如:
CFLAGS = $(include_dirs) -O
include_dirs = -Ifoo -Ibar
当"CFLAGS"在命令中展开时,会是"-Ifoo -Ibar -O"。但这种形式也有不好的地方,就是递归定义,如:
CFLAGS = $(CFLAGS) -O
或:
A = $(B)
B = $(A)
这会让 make 陷入无限的变量展开过程中去,当然,我们的make 是有能力检测这样的定义,并会报错。
还有就是如果在变量中使用函数,那么,这种方式会让我们的make 运行时非常慢,更糟糕的是,他会使
用得两个make 的函数“wildcard”和“shell”发生不可预知的错误。因为你不会知道这两个函数会被调用
多少次。
为了避免上面的这种方法,我们可以使用 make 中的另一种用变量来定义变量的方法。这种方法使用
的是“:=”操作符,如:
x := foo
y := $(x) bar
x := later
其等价于:
y := foo bar
x := later
值得一提的是,这种方法,前面的变量不能使用后面的变量,只能使用前面已定义好了的变量。