Vamos adicionar mais algum código de depuração.
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))
Saída:
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.
O problema é que a chamada eval
é feita antes da definição de VAR…
, no momento em que a função f1
é expandida, em vez de no momento em que o resultado dessa expansão é processado. Você precisa atrasar o eval
.
Além disso, há um erro de digitação na linha 1; Se você corrigir, você verá que o alvo all
não cria nada, pois TARGETS
não está definido no momento em que é usado. Você precisa declarar as dependências posteriormente.
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)