Expansão de macro Gmake: macro chama macro com variável em argumentos

1

No seguinte makeffile, um processo de macro é o argumento para chamar outra macro. Espero que o makefile abaixo gere dois alvos e corrija a lista de alvos em $ TARGETS. Mas, na verdade, só gera um alvo com a lista correta. Como fazer essa macro chamada de maneira correta?

all: $TARGETS
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))

saída do make:

test.mk:16: warning: overriding recipe for target 'target'
test.mk:15: warning: ignoring old recipe for target 'target'
test.mk:18: Warning: targetValueWithCallOne targetValueWithCallTwo
gmake: Nothing to be done for 'all'.
    
por gena2x 09.09.2014 / 13:52

1 resposta

1

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)
    
por 10.09.2014 / 09:55

Tags