根据相关的知识点,从以下几个方面进行总结。
makefile变量概述
在Makefile中的定义的变量,就像是C/C++语言中的宏一样,他代表了一个文本字串,在Makefile中执行的时候其会自动原模原样地展开在所使用的地方。
其与C/C++所不同的是,你可以在Makefile中改变其值。在Makefile中,变量可以使用在“目标”,“依赖目标”, “命令”或是Makefile的其它部分中。
变量命名规则
变量的命名字可以包含字符、数字,下划线(可以是数字开头),但不应该含有 : 、 # 、 = 或是空字符(空格、回车等)。变量是大小写敏感的,“foo”、“Foo”和“FOO”是三个不同的变量名。传统的Makefile的变量名是全大写的命名方式,但我推荐使用大小写搭配的变量名,如:MakeFlags。这样可以避免和系统的变量冲突,而发生意外的事情。
变量基础
变量在声明时需要给予初值,而在使用时,需要给在变量名前加上 $ 符号,但最好用小括号 () 或是大括号 {} 把变量给包括起来。如果你要使用真实的 $ 字符,那么你需要用 $$ 来表示。
例如:
objects = program.o foo.o utils.o
program : $(objects)
cc -o program $(objects)
$(objects) : defs.h
变量类似于c/c++宏
foo = c
prog.o : prog.$(foo)
$(foo)$(foo) -$(foo) prog.$(foo)
等价于:
prog.o : prog.c
cc -c prog.c
给变量加上括号完全是为了更加安全地使用这个变量,在上面的例子中,如果你不想给变量加上括号,那也可以,但还是强烈建议给变量加上括号。
变量当中的变量
变量的变量,也就是,变量的值可以是另外一个变量。
在变量的变量赋值过程当中,使用等号赋值,有好也有坏。
其中,前面定义的变量使用的值(也是变量)可以放在后面进行定义,这种方式,不好的地方在于容易造成递归循环。
为了解决这种问题,还有另外一种赋值方式,
也就是使用:=进行赋值。
当然,这种方式还可以结合判断语句和函数一起使用,这里就不进行总结了,后面使用时在进行总结。
变量高级用法
变量的高级语法这里,总结两点。
(1)变量值的替换
语法比较固定:
bar := a.o b.o
run := $(bar:.o=.c)
aa:
@echo $(run)
还有一种替换的方式,相比第一种就多了个%符号。
(2)把变量的值再当成变量
如果看不出变量的值到底是什么,可以加点打印语句观察。
追加变量值
可以使用+=进行变量值的追加
override指示符
我们实践一下。
aa:=hh
run:
@echo $(aa)
执行make命令时,重新为aa赋值,改变了makefile当中变量aa的值了,如果不想被改变,那么需要加上override指示符。
多行变量
参考:https://www.cnblogs.com/black-mamba/p/9637137.html
这里的$(bar)应该会被展开,我们实践下。
r:
@$(run)
bar=66
define run
echo $(bar)
echo 'aa'
endef
aa:
@$(run)
确实会展开bar变量。
这里要注意的就是在define和endef间定义的变量要用tab键开始。
环境变量
关于makefile的环境变量有很多,这里就不列举了,这类变量的使用注意事项如上。
目标变量
目标变量,顾名思义,即,对目标有关的变量。
看到最后一段的描述当中,我们不难看出,在prog这个目标或者是相关的依赖当中对它进行了相关变量的定义,如果其它地方的CFLAGS的值不是-g,那么就可以使用目标变量的方法。
模式变量
模式变量和目标变量有点类似,但是它相比于目标变量,在范围上显然更广一些。