测试是否在 Makefile 中定义了变量列表

Test if a list of variables are defined in a Makefile

我的 Makefile 基于配置文件或 ENV 变量中定义的多个变量。我目前的解决方案是手动测试所有这些:

NOGOAL = help clean distclean mrproper
ifeq ($(strip $(filter $(NOGOAL), $(MAKECMDGOALS))),)
VAR1 ?= $(error VAR1 undefined)
VAR2 ?= $(error VAR2 undefined)
VAR3 ?= $(error VAR3 undefined)
...
VARn ?= $(error VARn undefined)
endif

我想改用 foreach 循环:

ifeq ($(strip $(filter $(NOGOAL), $(MAKECMDGOALS))),)
TESTVAR = TEST1 TEST2 TEST3
$(foreach v, $(TESTVAR), $(eval $v ?= $$(warning Error: $v undefined)))
endif

不幸的是 eval 没有像我预期的那样工作。我错过了什么吗?

这里是我的测试的完整测试,包含 2 个测试实现。即使未定义 TEST3 我也不会收到任何错误

TEST1 = 1
TEST2 = 1
#TEST3 = 1   # NOT DEFINED


TESTVAR := TEST1 TEST2 TEST3

# First implementation
$(foreach v, $(TESTVAR), $(eval $v ?= $$(warning Error: $v undefined)))

# Second implementation
$(foreach v, $(TESTVAR), $(eval $(call TESTER,$v)))
define TESTER
ifndef 
$(warning  not defined)
endif
endef

# Dummy rule
all:
    @echo Hello World   

但是,如果我在某处使用 $(TEST3),我的第一个实现就可以工作。

编辑

这里我没有收到任何错误,但未定义 TEST3:

~$ cat Makefile
TEST1 = 1
TEST2 = 1
#TEST3 = 1   # NOT DEFINED


TESTVAR := TEST1 TEST2 TEST3

# First implementation
$(foreach v, $(TESTVAR), $(eval $v ?= $$(warning Error: $v undefined)))

# Dummy rule
all:
        @echo Hello World

~$ make
Hello World

好吧,我想我不明白。除非您使用未定义的变量之一,否则您所说的原始版本不会打印任何警告。您使用 foreach 的第一个替代方法的工作方式相同:它会打印警告,但仅当您 使用 未定义的变量时才会显示。

如果你想要那样,那么测试 clean 等并没有多大意义,因为这些规则可能不会使用未定义的变量,所以你不会得到任何错误(如果它们 确实 使用了未定义的变量,那么您可能希望这些规则也失败)。

但是在你的第二次编辑中,你说如果变量没有定义你希望 make 立即失败,不管它们是否被使用(在你最后的例子中你没有定义 TEST3,但您也没有对任何内容使用 TEST3,因此不会打印任何警告)。如果那是你想要的,我不明白你为什么要用 ?=eval 为变量赋值。只需写类似:

ifeq ($(strip $(filter $(NOGOAL), $(MAKECMDGOALS))),)
  $(foreach v,$(TESTVAR),$(if $($v),,$(error Error: $v undefined))
endif

(在这个版本中你需要检查MAKECMDGOALS因为它在一个未设置的变量上立即失败)。