Makefile使用变量
一、变量的命名规则
变量名字可以包含字符、数字(可以用在开头)、下划线,但不可以是: # = 或空字符。 变量是大小写敏感的。
二、变量的引用
在使用变量时,我们需要使用$符号告知 Makefile 我们即将使用变量,然后跟着变量名字。通常我们在变量名使用 () 或者{} 包裹。
三、变量的定义(赋值)
1. 递归展开式变量
var = value
递归展开式的变量在引用时,严格按照文本替换,变量的值原样出现在引用的地方。如果此变量的定义中存在对其他变量的引用,那么这些变量的也会在它被展开的同时被展开。就是说变量是递归展开的。
A=$(B)
B=$(C)
C=hello
all:echo $(A)
执行make展开的过程如下:
all:echo $(B)
all:echo $(C)
all:echo hello
最终输出hello。
这种变量的优点,就是在定义是,可以引用在它之前没有定义的变量。但缺点也很明显,容易造成变量的递归死循环,进而造成栈溢出。
2. 直接展开式变量
var := value
与递归展开式变量不同,变量值中对其他变量或函数的引用在定义(赋值)时就被展开,变量被定义之后其实质就是一个字符串文本,不包含其他未展开的变量。
因此,这种变量只能引用变量定义之前的变量,不能对其后赋值的或定义的变量进行引用。
3. 条件式变量
var ?= value
变量在此前没有定义(赋值)的情况下,才会讲值赋值给变量。如果已经定义则不会再次赋值。
4. 变量的替换引用
$(val:A=B)
替换val变量中的后缀字符串A,将A替换为B的字符串。
5. 追加变量
var += value
一个变量在赋值之后,在其后面可以对其进行字符串的追加。如果被追加的变量之前没有定义,那么相当于=的赋值。
6. override指示符
执行make的时候,我们可以定义变量,会覆盖Makefile中出现的同名变量的值。使用override可以对命令行定义的变量的值进行赋值。通常情况下是追加+=。
7. 多行定义
define val
......
endef
在define和endef之间的字符串都会作为变量的值。可以嵌套引用,可以包含换行符,空格等特殊符号。
8. 变量导出
export val
普通变量的可见性为本文件,make递归调用时,需要将变量导出给子makefile使用。
四、系统环境变量
make在运行时,系统中的左右环境变量对它都是可见的,所以在Makefile中可以引用任何已定义的系统环境变量。make的递归调用时,任何一个环境变量的错误赋值都会对系统上所有的make产生影响,因为环境变量具有全局性,所以尽量不要污染环境变量。