在下面的 makeffile 中,一个宏进程的参数是调用另一个宏。我希望下面的 makefile 将生成两个目标以及 $TARGETS 中的正确目标列表。但实际上它只生成一个具有正确列表的目标。如何以正确的方式进行这样的宏调用?
全部:$TARGETS 定义 f2 .PHONY:目标$(1) 目标$(1): echo“我们在$(1)” 目标+=目标$(1) 恩德夫 定义 f1 VAR$(1)=价值与$(1) $(eval $(调用 f2,$$(VAR$(1)))) 恩德夫 $(eval $(调用 f1,CallOne)) $(eval $(调用 f1,CallTwo)) $(警告警告:$(目标))
制作的输出:
test.mk:16:警告:覆盖目标“目标”的配方 test.mk:15:警告:忽略目标“目标”的旧配方 test.mk:18:警告:targetValueWithCallOne targetValueWithCallTwo gmake:对“全部”无需做任何事情。
答案1
让我们添加一些更多的调试代码。
all: $TARGETS
define f2
$$(info f2 called on $(1))
.PHONY: target$(1)
target$(1):
echo "We are in $(1)"
TARGETS+=target$(1)
endef
define f1
VAR$(1)=ValueWith$(1)
$(info too early: VAR$(1) is $$(VAR$(1)))
$$(info right time: VAR$(1) is $$(VAR$(1)))
$(eval $(call f2,$(VAR$(1))))
endef
$(eval $(call f1,CallOne))
$(eval $(call f1,CallTwo))
$(warning Warning: $(TARGETS))
输出:
too early: VARCallOne is $(VARCallOne)
f2 called on
right time: VARCallOne is ValueWithCallOne
too early: VARCallTwo is $(VARCallTwo)
f2 called on
debug.mk:18: warning: overriding commands for target `target'
debug.mk:17: warning: ignoring old commands for target `target'
right time: VARCallTwo is ValueWithCallTwo
debug.mk:20: Warning: target target
make: *** No rule to make target `ARGETS', needed by `all'. Stop.
问题在于,eval
调用是在 的 定义之前VAR…
、函数扩展时进行的f1
,而不是在处理扩展结果时进行的。你需要推迟一下eval
。
第 1 行也有一个错字;如果你修复它,你会发现目标all
没有构建任何东西,因为TARGETS
在使用它时没有定义。您需要稍后声明依赖关系。
all: # default target, declare it first
define f2
.PHONY: target$(1)
target$(1):
echo "We are in $(1)"
TARGETS+=target$(1)
endef
define f1
VAR$(1)=ValueWith$(1)
$$(eval $$(call f2,$$(VAR$(1))))
endef
$(eval $(call f1,CallOne))
$(eval $(call f1,CallTwo))
$(warning Warning: $(TARGETS))
all: $(TARGETS)