Makefileの奇妙なforeach +ユーザ定義関数の動作

私は次のMakefileを持っています:

X=a.jar b.jar c.jar
Y=/var/tmp/abc/a.jar /var/tmp/abc/b.jar /var/tmp/abc/c.jar

all: $(addprefix /var/tmp/abc/tmp/, $(X))

define AddRule
dst=$1
src=$2
/var/tmp/abc/tmp/$(dst): $(src)
        @echo [email protected]
        @echo $$^
        @mkdir -p $$(dir [email protected])
        @cp $$^ [email protected]
endef
$(foreach jar, $(X), $(eval $(call AddRule, $(jar), $(filter %$(jar), $(Y)))))

(/var/tmp/abc/{a,b,c}.jarが存在する)

基本的には、$ Xの各ファイル名に対して、$ Yのフルパスを見つけてそのファイルを/ var/tmp/abc/tmpにコピーするルールを作成したいと思います。私の実際のMakefileはもっと複雑で、このような構造が必要です)。

このMakefileを実行すると、次のような出力が得られます。

/var/tmp/abc/tmp/a.jar
/var/tmp/abc/a.jar
/var/tmp/abc/tmp/b.jar
/var/tmp/abc/b.jar
make: *** No rule to make target `/var/tmp/abc/tmp/c.jar', needed by `all'.  Stop.

今、 "面白い"部分: "すべて"ルールを宣言した後に次の行を追加すると:

X+=d

すべての3つのjarファイルが処理され、 'make'は 'd'について何も言及していません(ファイル 'd'が存在しない場合でも)、実行は成功です。

foreachループが最後の反復処理を行わないように見えます(あるいは、おそらく同じ結果につながる何かが起こるでしょう)。誰が問題が何で、どのように修正するかを知っていますか?

ありがとう!

1
追加された 編集された
ビュー: 1

1 答え

ループの最後の反復だけではありません。基本的には、 call が呼び出されたときに call が呼び出されたときに $(dst)評価される。次に、新しいコードが評価され、次の反復では、新しいコードの前のブロックによって設定された値で定義が展開されます。だから、{a、b、c}の代わりに{、a、b}を与えます(これを理解する前にこれをしばらく見なければなりません)。

解決策:いくつかの $

define AddRule
dst=$1
src=$2
/var/tmp/abc/tmp/$$(dst): $$(src)
    ...
endef
2
追加された
ありがとう!それはそれを修正!
追加された 著者 user1042699,