Makefile 奇妙な変数の置き換え

Makefile 奇妙な変数の置き換え

私のMakefile外観は次のとおりです。

%.foo: %.bar
    cp $< $@

test: *.foo
    echo *.foo

私のディレクトリには2つのファイルがあります:a.barb.bar。これを実行すると、make test出力は次のようになります。

cp b.bar *.foo
echo *.foo
*.foo

*.fooまた、現在のディレクトリにファイルを生成します。

実際、私はこれを見ることを期待していました:

cp a.bar a.foo
cp b.bar b.foo
echo *.foo
a.foo b.foo

そしてこれを達成する方法は何a.fooですか?b.foo

答え1

この場合、関数を使用してワイルドカードを明示的に処理する必要がありますwildcard(少なくともGNUが作る):

%.foo: %.bar
    cp $< $@

foos = $(patsubst %.bar,%.foo,$(wildcard *.bar))

test: $(foos)
    echo $(foos)

$(wildcard *.bar)で終わるすべてのファイルを展開し.bar、次にpatsubst置換を呼び出すと、すべてのターゲットが期待どおりに処理されます。.bar.foo

答え2

最初は* .fooファイルはありません。したがって、makeが行うことは、*.foo文字通りmakeを作成する方法を見つけることです。最初のルールはまさにそのことをします。 Makeは$<最初の前提条件(*.barこの場合は)に拡張されます。b.barその後、Makeはシェルコマンドを実行しますcp b.bar *.foo。 *.fooがないため、シェルはそれをcp b.bar *.foo文字通り拡張します。これが*.fooファイルを取得する方法です。

を実行してこれを確認できますmake -d test

前提条件リストに基づいて目標リストを作成することで、必要なものを得ることができます。

TARGETS = $(patsubst %.bar,%.foo,$(wildcard *.bar))
%.foo: %.bar
    @cp $< $@
test: $(TARGETS)
    @echo $(TARGETS)
    echo *.foo

関連情報