详解Makefile变量
Makefile变量
1、特征
(1)变量和函数的展开(除规则的命令行以外),是在make读取Makefile文件时进行的,这里的变量包括了使用“=”定义和使用的指示符“define”定义的变量。
(2)可以用来代表一个文件名列表、编译选项列表、程序运行的选项参数列表、搜索文件的目录列表、编译输出的目录列表和我们所能够想到的事物。
(3)变量名不能包括“:”、“#”、“=”、前置空白和尾空白的任何字符串。
(4)对大小写敏感,注意区分。
(5)有自动化变量的符号代表。
(6)变量的引用与Shell脚本类似,使用美元符号($)和圆括号--()。
2、分类
(1)自定义变量。 (常用)
例:
A = apple
B = I love China
C = $(A)tree -----C = apple tree
(2)系统预定义变量。
CFLAGS、CC、MAKE、SHELL等,这些变量已经有了系统预定义好的值,我们也可以给它们重新赋值,如CC的默认值是gcc。
(3)自动化变量。(@、^、<使用较多)
<、@、?、#等,这些特殊的变量之所以称为自动化变量,是因为它们的值会“自动地”发生变化,考虑普通的变量,只要不给它重新赋值,那么它的值是不变的。而自动化变量的值是不固定的,不能说@的值等于几,但是它的含义是固定的—@代表了其所在规则的目标的完整名称。
**************关于Makefile自动化变量及其变种的具体符号及其含义,参考博主博客《Makefile自动化变量及其变种》***********************
****************************************点击链接:http://blog.****.net/wu9797/article/details/77450395***************
3、定义方式
(1)递归定义方式。(常用)
例:
A = Love $(B)
B = China
在变量B出现之前,变量A的定义包含了对变量B的引用,由于A的定义方式是所谓的“递归”定义方式,因此当出现$(B)时会对全文件进行搜索,找到B的值并代进A中,A变量的结果为:“Love China”。
(2)直接定义方式。
B = China
A := I love $(B)
定义A是用的就是直接定义方式,即如果其定义里出现有队其他变量的引用,只会在其前面的语句进行搜寻,而不是搜索整个文件。所以,若:
A := I love $(B)
B = China
这样的话,定义A时B值为空。
(3)条件定义方式。
判断一个变量是否已经定义,如果已经定义了则不做操作,若没有则定义其值。
例:
A = apple
A ?= China
A ?=的含义就是,如果在A之前没有定义,则定义为China。前面已定义了A,故A还是apple,维持原值。
(4)多行命令定义方式。
例:
define commands
echo “Hello!”
echo “Thanks.”
endef
语法格式:以define开头,以endef结束。其所要定义的变量名必须在指示符define的同一行之后。
4、操作方式
(1)追加变量的值。
例:
A = apple
变量A的值就为apple tree了。A += tree
(2)修改变量的值。
例:
A = test1.c test2.c test3.c
B = $(A:%.c=%.o)
变零B的值就变成了test1.o test2.o test3.o。
(3)override一个变量。 (较少使用)
例:
override CFLAGS += -Wall
指示符override存在的目的是为了使用户可以改变或者追加那些使用make的命令行指定的变量的定义,也就是说实现了在Makefile中增加挥着修改命令行参数的一种机制。
(4)导出变量。 (常用)
例:
export CFLAGS = -Wall -g
导出变量的作用:使该变量可以传递给子Makefile。
对于默认会被传递给子Makefile的变量,可以使用unexport来阻止传递。
5、特殊变量
(1)VPATH (常用)
用于指定Makefile中文件的备用搜寻路径:当Makefile中国的目标文件或依赖文件不在当前路径时,make会在此变量所指定的目录中搜寻。如果VPATH包含多个备用路径,使用空格或者冒号隔开(一般使用冒号)。
例:
VPATH = src1/:arc2/
all: a b
a:a.c #如果make发现当前路径下不存在a.c,就会到VPATH中去找
gcc $^ -o [email protected]
b:b.c
gcc $^ -o [email protected]
注意:vpath为一个指示符,可以灵活地为各种不同的文件指定不同的路径。
例:
vpath %.c = src1/:arc2/ #指定本Makefile中.c文件的可能路径
vpath %.h = include/ #指定本Makefile中.h文件的可能路径
all:a b
a:a.c head.h
$(CC) $< -o [email protected]
b:b.c head.h
$(CC) $< -o [email protected]
(2)MAKE
当需要在Makefile中调用子Makefile时,需要用到MAKE变量,代表了当前系统中make软件的全路径。
例:
$(MAKE)-C subdir/
其中-C subdir/代表指定子Makefile所在目录。
(3)MAKEFLAGS (使用较少)
代表在执行make是的命令行参数,此变量默认会被传递给子Makefile。
例:
all:
echo $(MAKEFLAGS)
如使用make -hello命令,则会显示出hello,hello就是命令行参数。
参考书籍:林世霖《Linux环境编程图文指南》