私のMakefile
外観は次のとおりです。
%.foo: %.bar
cp $< $@
test: *.foo
echo *.foo
私のディレクトリには2つのファイルがあります:a.bar
とb.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