在 Makefile 中,有两种类型的变量:即时变量(immediate variable)和延迟变量(deferred variable)。
它们在 Makefile 的执行过程中具有不同的特性和行为。
即时变量(Immediate Variable):
即时变量在赋值时立即展开,也就是说,变量的值在赋值时就被计算并固定下来。
这意味着即时变量的值在整个 Makefile 的执行过程中都保持不变,不会受后续赋值或其他变量的改变而改变。
即时变量使用简单,直接赋值即可,
例如:CC := gcc
延迟变量(Deferred Variable):
延迟变量的值在使用时才会被展开,也就是说,变量的值在使用时才会被计算。
这意味着延迟变量的值会随着执行过程中其他变量的改变而改变,它具有一定的“延迟”特性。
使用延迟变量需要使用特殊的语法 ${VAR} 或者 $(VAR),例如:OBJ := $(SRC:.c=.o)
延迟变量通常用于需要动态计算的值,比如根据其他变量的值来计算最终结果的情况。这种特性使得 Makefile 可以更加灵活地根据当前情况动态生成变量值,从而适应各种不同的场景。
详细举例
当声明即时变量时,变量的值会立即展开。例如:
makefile
Copy Code
# 即时变量
CC := gcc
CFLAGS := -Wall -O2
app: main.c
$(CC) $(CFLAGS) -o app main.c
在这个例子中,CC 和 CFLAGS 都是即时变量。它们在赋值时就会被展开,后续对它们的引用都将使用赋值时的固定值。
而对于延迟变量,变量的值会在使用时才会被展开。例如:
makefile
Copy Code
# 延迟变量
SRC := file1.c file2.c file3.c
OBJ := $(SRC:.c=.o)
app: $(OBJ)
gcc -o app $(OBJ)
%.o: %.c
gcc -c -o $@ $<
在这个例子中,OBJ 是一个延迟变量,它的值在使用时才会被展开。当 app 目标需要依赖 $(OBJ) 时,OBJ 的值才会根据 SRC 的值动态计算并展开,将 .c 后缀替换为 .o 后得到最终的目标文件列表。
这两种变量的使用方式展示了它们的特性:即时变量在赋值时立即展开,而延迟变量的值在使用时才会被展开,可以根据当前情况动态计算。