变量就是给一串字符串起的名字。这串字符串就是变量的值。
变量的定义使用“=”或者使用指示符“define”。
变量的展开是严格的字符串替换。
变量的引用
Makefile 中:
在Makefile中,变量的引用方法:
$(VAR)
或者${VAR}
;
在Makefile中,不能使用$VAR
,除非变量名为单字符 。
Makefile 中符号$
有特殊的含义(表示变量或者函数的引用),在规则中需要使用符号$
本身的地方,需要书写两个连续的$$
。
shell 中:
在Shell中,变量的引用方法:
$VAR
或者${VAR}
;
在Shell中,不能使用$(VAR)
来引用变量。
Shell中的 $() 和 ` ` (反引号)
在bash shell中,$( )与 ` ` (反引号) 都是用来做命令替换(command substitution)用的。
$( )的不足: ` ` 基本上可在全部的unix shell中使用,脚本移植性比较高。而$( )并不是每一种shell都能使用。
Makefile 中在对一些简单变量的引用,我们也可以不使用$(x)
和${x}
来引用变量,而直接使用$x
的格式来实现,此种用法仅限于变量名为单字符的情况。另外自动化变量也使用这种格式。
对于一般多字符变量的引用必须使用括号,否则 make 将把变量名的首字母作为作为变量而不是整个字符串。如:$PATH
在 Makefile 中实际上是$(P)ATH
。这一点和 shell 中变量的引用方式不同。shell 中变量的引用可以是${xx}
或者$xx
格式。但在 Makefile 中多字符变量名的引用只能是$(xx)
或者${xx}
格式。
Makefile中避免Makefile的变量和Shell的变量相互混淆
Makefile中的三大基本元素:目标、依赖、命令。
其中:命令是在shell命令行下执行的命令,就可以理解为shell脚本中的执行的内容。
既然,shell脚本中能够有变量的使用,那么我们在Makefile的命令中也可以使用shell变量。
那么,如何让Makefile的变量和shell的变量不相互混淆呢?
# 例子一:
var = bcd
all:
var="abc";echo $${var}
# 例子一的输出结果:
zyao@ubuntu:~$ make
var="abc";echo ${var}
abc
zyao@ubuntu:~$
# 例子二:
var = bcd
all:
var="abc";echo ${var}
# 例子二的输出结果:
zyao@ubuntu:~$ make
var="abc";echo bcd
bcd
zyao@ubuntu:~$
# 例子三:
var = bcd
all:
var="abc";echo $(var)
# 例子三的输出结果:
zyao@ubuntu:~$ make
var="abc";echo bcd
bcd
zyao@ubuntu:~$
# 例子四:
var = bcd
all:
var="abc";echo $$(var)
# 例子四的输出结果:
zyao@ubuntu:~$ make
var="abc";echo $(var)
/bin/sh: var: command not found
zyao@ubuntu:~$
上述四个例子的分析:
-
例子二和例子三中 echo 出的是Makefile中的变量,其值为bcd
-
例子一中:
$$
表示此处需要的$
号本身,所以all目标所执行的命令相当于执行了脚本,脚本中的内容为:var="abc";echo ${var}
-
例子四中:相当于执行了一个脚本,脚本中的内容为:
var="abc";echo $(var)
,这样的脚本执行是会报错的。
一般在我们书写 Makefile 时,各部分变量引用的格式我们建议如下:
- make 变量(Makefile 中定义的或者是 make 的环境变量)的引用使用
$(VAR)
格式,无论 “VAR” 是单字符变量名还是多字符变量名。 - 出现在规则命令行中 shell 变量(一般为执行命令过程中的临时变量,它不属于Makefile 变量,而是一个 shell 变量)引用使用 shell 的
$tmp
格式。 - 对出现在命令行中的 make 变量我们同样使用
$(CMDVAR)
格式来引用。
# example
:
:
SUBDIRS := module1_src module2_src
subdir:
@for dir in $(SUBDIRS); do \
$(MAKE) -C $$dir || exit 1; \
done
:
: