以下のメイクファイルでは、あるマクロプロセスの引数は別のマクロを呼び出すことです。次のメイクファイルが$ 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)