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)

関連情報