一、概述
Makefile中使用的变量类似于C/C++中的宏,代表一个字符串。在Makefile执行过程中,变量会被替换成所代表的字符串。
变量的命名可以包含数字、字符、下划线,但不可以有“:”“#”“=”或者空字符。传统的Makefile变量全部大写,为避免和系统变量冲突,可能会大小写搭配。
二、变量的基础
变量在声明的时候需要给予初值,而在使用的时候,在变量名前加上“ ”字符,变量外用“()”或者“”括起,如$(OBJECT)。如果只是想使用字符$,那么使用$ 表示。
三、变量的变量
Makefile可以使使用变量值来构造变量。有两种方式,
a、使用“=”,此时=右侧的变量可以是之前没有定义的值,可以使用后面才定义的变量值;
b、使用“:=”,右侧只能是前面已经定义好的变量值。
“?=”表示如果变量没有被定义过,则值等于右侧的值。
四、变量的高级用法
1、变量值的替换
可以替换变量中共有的部分,格式为“$(var:a=b)”或者“${var:a=b}”,含义为将变量var中的字母a替换为字母b。
如
foo:=a.o b.o c.o
ret:=${foo:o=c}
则ret为a.c b.c c.c
2、变量值再当变量
嵌套定义
如
x=y
y=z
a:=$($(x))
则a为z
五、追加变量值
使用“+=”操作符表示给变量追加值:
如果变量之前没有被赋值,则“+=”会自动变为“=”;如果变量之前有赋值,则会自动继承之前的赋值,继续增加新的值;如果变量之前是以“:=”赋值,则“+=”自动以“:=”赋值。
如
obj =a.o b.o
obj +=c.o
$(obj)
最后的$(obj)的值为a.o b.o c.o
六、override提示符
如果有变量是通常make的命令行参数设置的,那么Makefile中对该值的赋值会被忽略;而如果想在Makefile中设置该参数值,可以通过override进行设置。格式
override <variable>=<value>或者
override <varibale>:=<value>
七、多行变量
使用define关键字,其后跟上变量名,另起一行为变量值,以endef结束。define前加Tab。如
define two-lines
echo a
echo b
endef
八、环境变量
系统的环境变量可以在make运行时载入到Makefile中,但如果Makefile中已经定义了这个环境变量或者make的命令行参数中已经指定了该环境变量参数,那么在该make运行时,系统变量值会被覆盖。
如果make运行时,指定了参数“e”,则Makefile中的环境变量值会被系统的环境变量值覆盖。
因此,如果系统设置了“CFLAGS”环境变量,则可以在所有的Makefile中使用该变量值。
当make嵌套调用时,上层Makefile中定义的变量会以系统环境变量的方式传递到下层Makefile中。默认情况下,只有通过命令行设置的参数才会传递,也可以通过在文件的变量前设置“export”表示可传递。
九、目标变量
之前提及的在Makefile中定义的变量均属于“全局性变量”,整个文件中均可访问。
自动化变量属于“规则型变量”,依赖于规则的目标和依赖目标的定义,也可以设置局部变量。
格式为
<target>:<varible-assignment>
或者
<target>:override <varible-assignment>
局部变量可以和全局变量名相同,但是在局部变量所属的规则及连带规则中,变量值为局部变量值。
如
prog:CFLAGS=-g
prog:prog.o main.o
$(CC) $(CFLAGS) prog.o main.o
此处CFLAGS为-g,不管全局变量值为多少。
十、模式变量
也可以将变量定义在符合某种模式的目标上,如%.o:CFLAGS=-o
格式为
<pattern>:<varible-assignment>
或者
<pattern>:override <varible-assignment>