아래 메이크파일에서 한 매크로 프로세스의 인수는 다른 매크로를 호출하는 것입니다. 다음 메이크파일이 $TARGETS에 대상과 올바른 대상 목록을 모두 생성하기를 바랍니다. 그러나 실제로는 올바른 목록이 있는 대상만 생성합니다. 이러한 매크로 호출을 올바른 방법으로 수행하는 방법은 무엇입니까?
모두: $TARGETS f2 정의 .PHONY: 타겟$(1) 목표$(1): echo "우리는 $(1)에 있습니다." 목표+=목표$(1) 엔데브 f1 정의 VAR$(1)=$(1)의 값 $(평가 $(f2 호출,$$(VAR$(1)))) 엔데브 $(평가 $(전화 f1,CallOne)) $(평가 $(전화 f1,CallTwo)) $(경고 경고: $(target))
생성된 출력:
test.mk:16: 경고: 'target' 대상에 대한 레시피 덮어쓰기 test.mk:15: 경고: 'target' 대상에 대한 이전 레시피가 무시되었습니다. 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)