测试是否在 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
因为它在一个未设置的变量上立即失败)。
我的 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
因为它在一个未设置的变量上立即失败)。