1. 变量的简单实用
Make的变量类似C的宏是种替换
= ,赋值
$( ) ,取变量值
2. 变量中的变量
在定义变量的值时,我们可以使用其它变量来构造变量的值,在 Makefile 中有四种方式来在用变量定义变量的值。第一种方式,也就是简单的使用“=”号,前面的变量可以使用后面定义的值。如:
foo = $(bar)
bar = $(ugh)
ugh = Huh?
第二种,前面不能使用后面的值 :=
:= foo
y := $(x) bar
x := later
其等价于:
y := foo bar
x := later
第三种,?=
如果左边变量没有被定义过,则定义为右边变量,由则不定义。
第四种,+=
追加变量值
3. 变量的替换
foo := a.o b.o c.o
bar := $(foo:.o=.c)
这个示例中,我们先定义了一个“$(foo)”变量,而第二行的意思是把“$(foo)”中所有以“.o”字串“结尾”全部替换成“.c”,所以我们的“$(bar)”的值就是“a.c b.cc.c”。
4. 变量种的变量:
x = variable1
variable2 := Hello
y = $(subst 1,2,$(x))
z = y
a := $($($(z)))
这 个 例 子 中 , “$($($(z)))” 扩 展 为 “$($(y))” , 而 其 再 次 被 扩 展 为 “$($(subst1,2,$(x)))”。$(x)的值是“variable1”,subst 函数把“variable1”中的所有“1”字串替换成“2”字串,于是,“variable1”变成“variable2”,再取其值,所以,最终,$(a)的值就是$(variable2)的值——“Hello”。(喔,好不容易)
5. override指示符
通常在执行make时,如果通过命令行定义了一个变量,那么它将替代在Makefile中出现的同名变量的定义。
如果不希望命令行指定的变量值替代在Makefile中的变量定义,那么我们需要在Makefile中使用指示符“override”来对这个变量进行声明,像下边那样:
override VARIABLE = VALUE
6. 多行变量
define 指示符后面跟的是变量的名字,而重起一行定义变量的值,定义是以 endef 关键字结束。其工作方式和“=”操作符一样。变量的值可以包含函数、命令、文字,或是其
它变量。因为命令需要以[Tab]键开头, 所以如果你用 define 定义的命令变量中没有以[Tab]键开头,那么 make 就不会把其认为是命令。下面的这个示例展示了 define 的用法:
define two-lines
echo foo
echo $(bar)
endef
7. 环境变量
Make 运行时的系统环境变量可以在 make 开始运行时被载入到 Makefile 文件中,但是如果 Makefile 中已定义了这个变量,或是这个变量由 make 命令行带入,那么系统的环境变量的值将被覆盖。
上层 Makefile 中定义的变量会以系统环境变量的方式传递到下层的 Makefile 中。当然,默认情况下,只有通过命令行设置的变量会被传递。而定义在文件中的变量,如果要向下层 Makefile 传递,则需要使用exprot 关键字来声明。
环境变量如CPPFLAGS等
8. 局部变量
<target ...> : <variable-assignment>
<target ...> : overide <variable-assignment>
<variable-assignment>可以是前面讲过的各种赋值表达式,如“=”、“:=”、“+=”
或是“?=”。第二个语法是针对于 make 命令行带入的变量,或是系统环境变量。这个特性非常的有用,当我们设置了这样一个变量,这个变量会作用到由这个目标所引发的所有的规则中去。如:
prog : CFLAGS = -g
prog : prog.o foo.o bar.o
$(CC) $(CFLAGS) prog.o foo.o bar.o
在这个示例中,不管全局的$(CFLAGS)的值是什么,在 prog 目标,以及其所引发的所有规则中(prog.o foo.o bar.o 的规则),$(CFLAGS)的值都是“-g”
9. 模式变量
模式变量的好处就是,我们可以给定一种
“模式”,可以把变量定义在符合这种模式的所有目标上。我们知道,make 的“模式”一般是至少含有一个“%”的,所以,我们可以以如下方式给所有以[.o]结尾的目标定义目标变量:
%.o : CFLAGS = -O