我的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
并没有像我预期的那样奏效。我错过了什么吗?
这里对我的测试进行了全面测试,包括两个测试实现。即使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 $1
$(warning $1 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
答案 0 :(得分:1)
嗯,我想我不明白。您说的原始版本按照您希望的方式工作,除非您使用未定义的变量之一,否则不会打印任何警告。使用foreach
的第一个替代方法的工作方式相同:只有在使用未定义的变量时才会打印警告。
如果你想这样,那么测试clean
等并没有多大意义,因为大概这些规则不会使用未定义的变量,所以你不会得到任何错误(如果他们 使用未定义的变量,可能你也希望这些规则失败)。
但是在第二次编辑中,如果未定义变量,则表示您希望make立即失败,无论它们是否被使用(在上一个示例中,您没有定义TEST3
,但是你没有使用TEST3
,所以没有打印警告)。如果这就是您想要的,我不明白您为什么要使用?=
或使用eval
为变量分配值。只需写下:
ifeq ($(strip $(filter $(NOGOAL), $(MAKECMDGOALS))),)
$(foreach v,$(TESTVAR),$(if $($v),,$(error Error: $v undefined))
endif
(在此版本中,您执行需要检查MAKECMDGOALS
,因为它在未设置的变量上立即失败。)