一 变量概述:
(1)在Makefile中,变量代表一个文本字串,可以在目标(targets),依赖目标,命令或是Makefile的其它部分中使用。
(2)变量的名字可以包含字符、数字和下划线。变量对大小写敏感。传统的变量名为全大写,但推荐使用大小写混搭的变量名。
二 变量基础:
(1)变量声明时需要给予初值,使用时,需要在变量名前加上“$”符号,但最好用小括号“()”或大括号“{}”把变量给包括起来。不加括号可以,但是强烈建议还是加上。如果要使用真实的“$”字符,那么需要用“$$”表示。
(2)可以在目标(targets),依赖目标,命令或是Makefile的其它部分中使用:
objects = program.o foo.o utils.o
program : $(objects)
cc -o program $(objects)
$(objects) : defs.h
三 变量的定义:
(1)在定义变量的值时,可以使用其它变量来构造变量的值。在Makefile中有两种方式定义。
(2)第一种方式:简单使用“=”号,在“=”左侧是变量,右侧是变量的值。右侧变量的值可以定义在文件的任何一处,即可以使用后面定义的值。如:
foo = $(bar)
bar = $(ugh)
ugh = Huh?
all:
echo $(foo)
*make all打印出$(fpp)的值时“Huh?”。
*优点:可以把变量的真实值推倒后面来定义。
*缺点:递归定义。例如:
A=$(B)
B=$(A)
(3)第二种方式:使用“:=”操作符。前面的变量不能使用后面的变量,只能使用前面已定义好的变量。
(4)操作符“?=”。例如:FOO?=bar:如果FOO没有被定义过,那么变量FOO就是"bar";如果FOO先前被定义过,那么这条语句什么也不做。
四 变量高级用法:
(1)变量值的替换:
*格式:$(var:a=b)或${var:a=b}:把变量var中所有以“a”字串结尾的“a”替换成“b”字串。结尾:"空格"或“结束符”。
*格式:$(var:%s=%b),同上。
(2)把变量值再当成变量:
*例如:
x=y
y=z
则echo $($x)为:z。
五 追加变量值:
(1)使用“+=”操作符给变量追加值。
六 override提示符:
(1)如果有变量是通过make的命令行参数设置的,那么Makefile中对这个变量的赋值将被忽略。如果想在Makefile中设置这类参数的值,可以使用"override"操作符。
(2)语法:
override<variable>=<value>
override<variable>:=<value>
override<variable>+=<value>
七 多行变量(define):
(1)define 指示符后面跟的是变量的名字,而重起一行定义变量的值,定义是以 endef 关键字结束。其工作方式和“=”操作符一样。变量的值可以包含函数、命令、文字,或是其它变量。
(2)格式(=可选,不是必须):
define two-lines =
echo foo
echo $(bar)
endef
八 环境变量:
(1)make 运行时的系统环境变量可以在 make 开始运行时被载入到 Makefile 文件中,但是如果Makefile 中已定义了这个变量,或是这个变量由 make 命令行带入,那么系统的环境变量的值将被覆盖。
(2)因此,如果我们在环境变量中设置了“CFLAGS”环境变量,那么我们就可以在所有的Makefile中使用这个变量了。这对于我们使用统一的编译参数有比较大的好处。如果Makefile中定义了 CFLAGS,那么则会使用 Makefile 中的这个变量,如果没有定义则使用系统环境变量的值,一个共性和个性的统一,很像“全局变量”和“局部变量”的特性。
(3)当 make 嵌套调用时,上层 Makefile 中定义的变量会以系统环境变量的方式传递到下层的 Makefile 中。当然,默认情况下,只有通过命令行设置的变量会被传递。而定义在文件中的变量,如果要向下层 Makefile 传递,则需要使用 export关键字来声明。
九 目标变量(Target-specific Variable):
(1)可以为某个目标设置局部变量,作用域只在这条规则以及连带规则中,其值只在作用范围内有效。不会映射规则链之外的全局变量的值。
(2)语法:
*语法1:
<target ...> : <variable-assignment>
<target ...> : overide <variable-assignment>
<variable-assignment>可以是前面讲过的各种赋值表达式,如“=”、“:=”、“+=”或是“?=”。
*语法2:make 命令行带入的变量,或是系统环境变量。
(3)例如:
prog : CFLAGS = -g
prog : prog.o foo.o bar.o
$(CC) $(CFLAGS) prog.o foo.o bar.o
prog.o : prog.c
$(CC) $(CFLAGS) prog.c
foo.o : foo.c
$(CC) $(CFLAGS) foo.c
bar.o : bar.c
$(CC) $(CFLAGS) bar.c
在这个示例中,不管全局的$(CFLAGS)的值是什么,在 prog 目标,以及其所引发的所有规则中(prog.o foo.o bar.o 的规则),$(CFLAGS)的值都是“-g” 。
十 模式变量:
(1)模式变量的好处:给定一种模式,可以把变量定义在符合这种模式的所以目标上。
(2)使用:
*所有以[.o]结尾的目标定义目标变量:
%.o : CFLAGS = -O
同样,模式变量的语法和“目标变量”一样:
<pattern ...> : <variable-assignment>
<pattern ...> : override <variable-assignment>
*override 同样是针对于系统环境传入的变量,或是 make 命令行指定的变量。