跟C语言一样 Makefile也支持变量,Makefile中的变量都是字符串,类似 C语言中的宏(执行时替换)。
举例:
main: main.o input.o calcu.o
gcc -o main main.o input.o calcu.o
#使用变量减少输入
objects = main.o input.o calcu.o
main: $(objects)
gcc -o main $(objects)
各种赋值符号
=赋值
使用“=”在给变量的赋值的时候,不一定要用已经定义好的值,也可以使用后面定义的值,即某变量最后的真实值。“=”的神奇之处!借助另外一个变量,可以将变量的真实值推到后面去定义。也就是变量的真实值取决于它所引用的变量的最后一次有效值。
举例:
name = br
curname = $(name)
name = barretren
print:
@echo curname: $(curname)
#curname最终的值为barretren
:=赋值
:=赋值符号与=的不同是,:=只能使用变量前面定义好的值,不能使用后面变化后的最终有效值。
相同的例子,输出不一样:
name = br
curname := $(name)
name = barretren
print:
@echo curname: $(curname)
#curname最终的值为br
?=赋值
?=具有一个检查效果:
- 如果该变量已经赋值了,则使用?=赋新值则不起作用,继续使用原来的值;
- 如果之前没有赋值,则使用?=后面的值,等同于=赋值
name = br
curname := $(name)
name = barretren
curname ?= barretren # 前面赋值了,这里赋值不起作用
print:
@echo curname: $(curname)
#curname最终的值为br
+=赋值
因为makefile中变量实质都是字符串,左右可以使用+=追加新字符串内容,和原内容之间默认增加空格分隔开:
name = br
curname := $(name)
name = barretren
curname += haha # 追加内容
print:
@echo curname: $(curname)
#curname最终的值为br haha
自动变量
成对应的目标?自动化变量就是完成这个功能的!所谓自动化变量就是这种变量会把模式中所定义的一系列的文件自动的挨个取出,直至所有的符合模式的文件都取完,自动化变量只应该出现在规则的命令中。
自动化变量 | 描述 |
---|---|
$@ | 规则中的目标集合,在模式规则中,如果有多个目标的话,“$@”表示匹配模式中定义的目标集合。 |
$% | 当目标是函数库的时候表示规则中的目标成员名,如果目标不是函数库文件,那么其值为空。 |
$< | 依赖文件集合中的第一个文件,如果依赖文件是以模式(即“%”)定义的,那么“$<”就是符合模式的一系列的文件集合。 |
$? | 所有比目标新的依赖目标集合,以空格分开。 |
$^ | 所有依赖文件的集合,使用空格分开,如果在依赖文件中有多个重复的文件,“$^”会去除重复的依赖文件,只保留一份。 |
$+ | 和“$^”类似,但是当依赖文件存在重复的话不会去除重复的依赖文件。 |
$* | 这个变量表示目标模式中”%”及其之前的部分,如果目标 是 test/a.test.c,目标模式为 a.%.c,那么 “$*”就是 test/a.test。 |
举例:
# 模式规则
# %表示长度任意的非空字符串,
%.o : %.c # 代指所有c文件生成对应的o目标文件
gcc -c $< # $<表示依赖集合中每个文件