在Makefile中,=
、:=
、?=
和 +=
是用于定义和操作变量的不同赋值运算符,它们各自有其特点和用途。下面详细介绍:
1. =
(递归扩展变量赋值)
- 特点:这种赋值方式会在使用变量时才进行扩展,并且会递归地展开所有依赖的变量。这意味着,如果在变量定义中引用了其他尚未完全定义的变量,Make 会在使用该变量时去查找最新的值。
- 示例:
A = $(B)
B = $(C)
C = world
hello:
@echo $(A)
在这个例子中,当 $(A)
被使用时,它会递归地查找 $(B)
和 $(C)
的值,最终输出 world
。
2. :=
(简单扩展变量赋值)
- 特点:这种赋值方式在定义变量时就立即进行扩展,只对当前已经定义的变量进行替换。之后对其他相关变量的修改不会影响到这个变量的值。
- 示例:
A := $(B)
B = world
hello:
@echo $(A)
这里,$(A)
在定义时,$(B)
还未定义,所以 $(A)
的值为空。如果将顺序调整为:
B = world
A := $(B)
hello:
@echo $(A)
则 $(A)
的值为 world
,并且之后对 B
的修改不会影响 A
。
3. ?=
(条件变量赋值)
- 特点:只有当变量尚未被定义时,才会进行赋值操作。如果变量已经被定义,那么这个赋值语句将被忽略。
- 示例:
A := initial value
A?= new value
hello:
@echo $(A)
在这个例子中,由于 A
已经被定义为 initial value
,A?= new value
这一行不会生效,所以最终输出 initial value
。如果 A
没有被预先定义,那么 A
将被赋值为 new value
。
4. +=
(追加变量赋值)
- 特点:用于向已定义的变量追加值。如果变量尚未定义,它会先创建该变量并赋值。
- 示例:
A := hello
A += world
hello:
@echo $(A)
这里,A
最初被赋值为 hello
,然后通过 +=
追加了 world
,最终输出 hello world
。如果 A
一开始没有被定义,A += world
会直接创建 A
并赋值为 world
。
通过合理使用这些赋值运算符,可以在 Makefile 中灵活地定义和管理变量,以满足不同的构建需求。