变量的命名字可以包含字符、数字,下划线(可以是数字开头),区分大小写。
1.变量的基础:
变量在声明时需要给予初值,而在使用时,需要给在变量名前加上“$”符号。
注:如果你要使用真实的“$”字符,那么你需要用“$$”来表示。
2.变量中的变量:
在定义变量的值时,我们可以使用其它变量来构造变量的值,在 Makefile 中有两种方式来在用变量定义 变量的值。
第一种方式,也就是简单的使用“=”号,在“=”左侧是变量,右侧是变量的值,右侧变量的值可以定义在文件 的任何一处,也就是说,右侧中的变量不一定非要是已定义好的值,其也可以使用后面定义的值。
第二种方式,这种方法使用的是“:=”操作符。
注:第二种方式,前面的变量不能使用后面的变量,只能使用前面已定义好了的变量。
再说一个定义变量需要知道的知识,如果定义一个变量,值为一个空格,可以这样定义。
nullstring :=
space := $(nullstring)#end of the line
nullstring 是一个Empty 变量,其中什么也没有,而我们的space 的值是一个空格。因为在操作符的右边是很难描述一个空格的,这里采用的技术很管用,先用一个Empty 变量来标明变量的值开始了,而后面采用“#”注释符来表示变量定义的终止,这样,我们可以定义出其值是一个空格的变量。请注意这里关于“#”的使用,注释符“#”的这种特性值得我们注意,如果我们这样定义一个变量:
dir := /foo/bar # directory to put the frobs in
dir 这个变量的值是“/foo/bar”,后面还跟了4 个空格,如果我们这样使用这样变量来指定别的目录——“$(dir)/file”那么就完蛋了
还有1个比较有用的操作符“?=”例:
FOO ?= bar
含义是,如果FOO 没有被定义过,那么变量FOO 的值就是“bar”,如果FOO 先前被定义过,那么这条语将什么也不做。
3.变量高级用法:
第1种是变量值的替换。其格式是“$(var:a=b)”或是“${var:a=b}”,其意思是,把变量“var”中所有以“a”字串“结尾”的“a”替换成“b”字串。这里的“结尾”意思是“空格”或是“结束符”。还是看一个示例:
foo := a.o b.o c.o
bar := $(foo:.o=.c) # .c instead of .o
例:
a_objects := a.o b.o c.o
1_objects := 1.o 2.o 3.o
sources := $($(a1)_objects:.o=.c)
这个例子中,如果$(a1)的值是“a”的话,那么,$(sources)的值就是“a.c b.c c.c”;如果$(a1)的值是“1”,那么$(sources)的值是“1.c 2.c 3.c”。
第2种变量替换是以“静态模式”,如:
foo := a.o b.o c.o
bar := $(foo:%.o=%.c) # .c instead of .o
4.追加变量值
可以使用“+=”操作符给变量追加值。如果变量之前没有定义过,那么,“+=”会自动变成“=”,如果前面有变量定义,那么“+=”会继承于前次操作的赋值符。如果前一次的是“:=”,那么“+=”会以“:=”作为其赋值符。
例:
objects = main.o foo.o bar.o utils.o
objects += another.o
5.override 指示符
如果有变量是通常make的命令行参数设置的,那么Makefile中对这个变量的赋值会被忽略。如果你想在Makefile中设置这类参数的值,那么,你可以使用“override”指示符。其语法是:
override =
override :=
6.多行变量
还有一种设置变量值的方法是使用 define 关键字。使用define 关键字设置变量的值可以有换行,这有利于定义一系列的命令。define 指示符后面跟的是变量的名字,而重起一行定义变量的值,定义是以endef 关键字结束。其工作方式和“=”操作符一样。变量的值可以包含函数、命令、文字,或是其它变量。因为命令需要以[Tab]键开头,所以如果你用define 定义的命令变量中没有以[Tab]键开头,那么make 就不会把其认为是命令。例:
define two-lines
echo foo
echo $(bar)
endef
7.环境变量 make运行时系统环境变量可以在make开始运行时被载入到Makefile文件中,但如果Makefile中已定义了这个变量,或是这个变量由make 命令行带入,那么系统的环境变量的值将被覆盖。(如果make 指定了“-e”参数,那么,系统环境变量将覆盖Makefile 中定义的变量)。
因此,如果我们在环境变量中设置了“CFLAGS”环境变量,那么我们就可以在所有的Makefile 中使用这个变量了。这对于我们使用统一的编译参数有比较大的好处。如果Makefile 中定义了CFLAGS,那么则会使用Makefile 中的这个变量,如果没有定义则使用系统环境变量的值,一个共性和个性的统一,很像“全局变量”和“局部变量”的特性。当 make 嵌套调用时,上层Makefile 中定义的变量会以系统环境变量的方式传递到下层的Makefile 中。当然,默认情况下,只有通过命令行设置的变量会被传递。而定义在文件中的变量,如果要向下层Makefile 传递,则需要使用exprot 关键字来声明。8.目标变量(Target-specific Variable) 可以为某个目标设置局部变量,这种变量被称为目标变量,它可以和“全局变量”同名,因为它的作用范围只在这条规则以及连带规则中,所以其值也只在作用范围内有效。而不会影响规则链以外的全局变量的值。
其语法是:
:
: overide
可以是前面讲过的各种赋值表达式,如“=”、“:=”、“+=”或是“?=”。第二个语法是针对于make 命令行带入的变量,或是系统环境变量。这个特性非常的有用,当我们设置了这样一个变量,这个变量会作用到由这个目标所引发的所有的规则中去。例:
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”。
9.模式变量(Pattern-specific Variable) 在 GNU 的make中,还支持模式变量,通过上面的目标变量中,我们知道,变量可以定义在某个目标上。模式变量的好处就是,我们可以给定一种“模式”,可以把变量定义在符合这种模式的所有目标上。我们知道,make的“模式”一般是至少含有一个“%”的,所以,我们可以以如下方式给所有以[.o]结尾的目标定义目标变量:
%.o : CFLAGS = -O
同样,模式变量的语法和“目标变量”一样:
:
: override
override同样是针对于系统环境传入的变量,或是make命令行指定的变量。
阅读(836) | 评论(0) | 转发(0) |