Gmake 매크로 확장: 매개변수에 변수가 있는 매크로 호출

Gmake 매크로 확장: 매개변수에 변수가 있는 매크로 호출

아래 메이크파일에서 한 매크로 프로세스의 인수는 다른 매크로를 호출하는 것입니다. 다음 메이크파일이 $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)

관련 정보