web-dev-qa-db-ja.com

GNU Makeパターンルールでワイルドカードを使用する

doc.pdfがターゲットであると想定します。

次のルールは、doc.pdfが更新されるたびにdoc.referの再生成をトリガーしますが、doc.referがまったく存在しない場合にも満足します。

doc.pdf: doc.mom $(wildcard doc.refer)
    pdfmom -e -k < $< > $@

ただし、次のパターンルールでは同じことが実現されません(PDFは正しく生成されますが、doc.referを変更しても再構築はトリガーされません)。

%.pdf: %.mom Makefile $(wildcard %.refer)
    pdfmom -e -k < $< > $@

%文字が展開される前にwildcardコマンドが実行されていると思います。どうすればこれを回避できますか?

7
not-a-user

The GNU Make function wildcard は、シェルグロビングパターンを受け取り、そのパターンに一致するファイルに展開します。パターン%.referは、シェルのグロビングパターンを含みます。

あなたはおそらく次のようなものが必要です

%.pdf: %.mom %.refer
        pdfmom -e -k < $< > $@

%.pdf: %.mom
        pdfmom -e -k < $< > $@

最初のターゲットは、.momがある場合にPDFファイルを作成するために呼び出され、.referファイルはドキュメントのベース名に使用できます。2番目のターゲットは、.referファイルが使用できない場合に呼び出されます。

これらのターゲットの順序は重要です。

12
Kusalananda

あなたはおそらく Secondary Expansion を使用することができます:

.SECONDEXPANSION:
%.pdf: %.mom Makefile $$(wildcard %.refer)
    pdfmom -e -k < $< > $@

GNU Makeは、パターンルールの内部表現を生成するためにすべての関数を評価します。

したがって、$(wildcard %.refer)は、ルールに対して空の文字列と評価されました。

あなたの目標を達成する唯一の方法は、Kusalanandaのようなルールの順序付けを利用することです(info "(make)Pattern Match")

10.5.4 How Patterns Match

   It is possible that more than one pattern rule will meet these
criteria.  In that case, 'make' will choose the rule with the shortest
stem (that is, the pattern that matches most specifically).  If more
than one pattern rule has the shortest stem, 'make' will choose the
first one found in the makefile.
1
gavenkoa