你可以这样做。下面是方法,假设这undef
是您要用于取消定义变量的目标的名称。
FOO:=foo
ifeq (undef,$(filter undef,$(MAKECMDGOALS)))
override undefine FOO
endif
.PHONY: all
all:
echo $(FOO) '($(origin FOO))'
.PHONY: undef
undef: $(if $(filter-out undef,$(MAKECMDGOALS)),,$(.DEFAULT_GOAL)))
make
使用元素说明:
MAKECMDGOALS
是预定义的只读变量,包含make
调用的目标。我们使用它来检查是否make
被调用undef
。
.DEFAULT_GOAL
是包含默认目标的预定义变量。如果未明确设置,则将其设置为第一个目标,在本例中为all
.
ifeq
...endif
允许 a 中的条件部分Makefile
。
- 该
$(filter pattern,list)
函数返回list
与 匹配的所有元素pattern
。因此,如果作为其目标之一make
被调用,则将是,否则它将是空字符串。undef
$(filter undef,$(MAKECMDGOALS))
undef
$(filter-out pattern,list)
功能是相反的$(filter key,list)
。它返回所有与list
不匹配的元素pattern
。因此,如果仅使用,make
将是空字符串,否则它将是命令行上给出的所有目标的列表,不包括.undef
$(filter-out undef,$(MAKECMDGOALS))
undef
undefine
取消定义变量。
override
即使它是在命令行上传递的,也会更改变量。您需要根据您的用例决定使用是否override
有意义。
- 如果为真,则该
$(if cond,then[,else])
函数返回,否则(如果没有,则返回空字符串)。非空字符串为真,空字符串为假。then
cond
else
else
因此,Makefile 取消定义FOO
以防万一undef
在命令行中给出。
的“神奇”依赖undef
确保 ifundef
是命令行上给出的唯一目标,它将依赖并因此执行默认目标,在本示例中为all
. 这是为了确保它的make undef
行为类似于make
它取消定义变量。
警告:此类Makefile
s 的行为可能令人困惑。想象一个 Makefile 使用这种机制来排除CPPFLAGS+=-DNDEBUG
万一debug
被给定的情况。出乎意料的是,make debug all
并make all
为. 与 相比,预期会产生额外的输出。主要的期望是,无论命令行上可能另外存在什么其他目标,它的行为总是相同的。最好使用-style 机制来实现此类机制。make all
make debug all
make all
make all
configure
(来源:来自我未出版的关于 GNU make 的书。)