插播!插播!插播!亲爱的朋友们,我们的Makefile课程上线啦!感兴趣的小伙伴可以去下面的链接学习哦~
https://edu.csdn.net/course/detail/39264
当我们定义了一个变量之后,就可以在 Makefile 的很多地方使用这个变量。变量 的引用方式是:“$(VARIABLE_NAME)”或者“${ VARIABLE_NAME }”来引用一个 变量的定义。例如:“$(foo) ”或者“${foo}”就是取变量“foo”的值。对一个变量的引用可以在 Makefile 的任何上下文中,目标、依赖、 命令、绝大多数指示符和新变量的赋值中。举例说明:
例如上述Makefile
.PHONY:clean
all:test
test:add.o operation.o
gcc -o test add.o operation.o
operation.o:operation.c
gcc -o operation.o -c operation.c
add.o:add.c
gcc -o add.o -c add.c
clean:
rm -rf test add.o operation.o
可将OBJS = add.o operation.o ,CC=gcc BIN=test
则上述Makefile等同于以下Makefile
.PHONY:clean
CC=gcc
OBJS = add.o operation.o
BIN = test
$(BIN):$(OBJS)
$(CC) -o $@ $^
%.o:%.c
$(CC) -o $@ -c $^
clean:
rm -f $(BIN) $(OBJS)
2.1 变量的赋值
追加赋值:
通常,一个通用变量在定义之后的其他一个地方,可以对其值进行追加。这是非常 有用的。我们可以在定义时(也可以不定义而直接追加)给它赋一个基本值,后续根据 需要可随时对它的值进行追加(增加它的值)。在 Makefile 中使用“+=”(追加方式) 来实现对一个变量值的追加操作:例如:
OBJECT = hello
OBJECT +=world
all:
@echo "$(OBJECT)"
编译执行后,终端会出现helloworld
条件赋值:
GNU make 中,还有一个被称为条件赋值的赋值操作符“?=”。被称为条件赋值是 因为:只有此变量在之前没有赋值的情况下才会对这个变量进行赋值。
OBJECT ?= 8
all:
@echo "$(OBJECT)"
编译执行后,终端会出现8,如果变量在之前已经赋值,则条件赋值不会对其变量产生作用。
OBJECT = 7
OBJECT ?= 8
all:
@echo "$(OBJECT)"
编译执行后,终端会出现7。
2.2 立即展开变量
GNU make 支持另外一种风 格的变量,称为“直接展开”式。这种风格的变量使用“:=”定义。在使用“:=”定义 变量时,变量值中对其他量或者函数的引用在定义变量时被展开(对变量进行替换)。 所以变量被定义后就是一个实际需要的文本串,其中不再包含任何变量的引用。举例说明:
x := foo
y := $(x) bar
x := later
相当于以下
y := foo bar
x := later
此风格变量在定义时就完成了对所引用变量和函数的展开,因 此不能实现对其后定义变量的引用。
2.3 延迟展开变量
这一类型变量的定义是通过“=”定义的。在变量定义时,变量值中对其他变量的引用不会被替换展开;而是变量在引用它的地方替换展开的同时,它所引用的其它变量才会被 一同替换展开。举例说明:
foo = $(bar)
bar = $(ugh)
ugh = Huh?
all:
echo $(foo)
执行“make”将会打印出“Huh?”这种类型变量在定义时,可以引用其它的之前没有定义的变量(可能在后续部分定义, 或者是通过 make 的命令行选项传递的变量)
2.4 全局变量
在Makefile中,全局变量指的是可以在整个Makefile中使用的变量,与局部变量相对。全局变量可以用来存储各种配置信息、路径信息等。定义全局变量的方法是,在Makefile的顶部使用“变量=值”或“变量:=值”语法进行定义。例如:
CC = gcc
需要注意的是,如果在Makefile中定义了一个全局变量,而在某个规则中定义了同名的局部变量,那么在这个规则中会使用局部变量而非全局变量。因此,为了避免这种问题,建议尽量使用独特的变量名。
2.5 目标变量
在Makefile中,目标变量是指某个规则中的目标文件名所对应的变量。目标变量通常用于指定目标文件名,以实现在编译不同目标时生成不同的输出文件。目标变量的定义通常使用“目标: 变量名 = 值”的语法。例如:
all:test
OBJS=add.o
test:OBJ = $(OBJS)
test:$(OBJ)
gcc -o $(OBJ) test
需要注意的是,在使用目标变量时,必须确保目标变量的值在规则中被定义。如果没有定义目标变量的值,Make会报错并终止编译。
2.6 模式变量
模式变量是指可以使用通配符和模式匹配来定义的变量。