~によるとGNU製作マニュアル
複数の目標を持つルールは、それぞれが目標を持つ複数のルールを作成するのと同じで、その他は同じです。同じレシピがすべてのターゲットに適用されますが、「$@」を使用して実際のターゲット名をレシピに変更できるため、効果が異なる場合があります。さらに、この規則はすべてのターゲットに対して同じ前提条件を提供します。
最初に生成されたファイル:
%.in %.out:
echo BLANK > $@
対応するbashセッション:
$ ls
Makefile
$ make a.in a.out
echo BLANK > a.in
make: Nothing to be done for 'a.out'.
$ ls
Makefile a.in
$ make a.out
echo BLANK > a.out
$ ls
Makefile a.in a.out
$ make b.in c.out
echo BLANK > b.in
echo BLANK > c.out
$ make d.in d.out
echo BLANK > d.in
make: Nothing to be done for 'd.out'.
$ make e.out e.in
echo BLANK > e.out
make: Nothing to be done for 'e.in'.
$ ls
Makefile a.in a.out b.in c.out d.in e.out
2番目の生成されたファイル:
%.in:
echo BLANK > $@
%.out:
echo BLANK > $@
対応するbashセッション:
$ ls
Makefile
$ make a.in a.out
echo BLANK > a.in
echo BLANK > a.out
$ ls
Makefile a.in a.out
$ # nice
したがって、質問は次のようになります。
最初のMakefileがターゲット<name>.in <same name>.out
を生成しないのはなぜですか?解釈が2番目のMakefileと似ていないのはなぜですか?
答え1
あなたのルールによると、make
レシピへの単一の呼び出しで両方そして目標.in
。.out
https://www.gnu.org/software/make/manual/html_node/Pattern-Intro.htmlこれについて説明します。 (第2段落では)次のように言います。
パターンルールには複数のターゲットを含めることができますが、各ターゲットには%文字を含める必要があります。記号。
次のリンクをクリックしてください多くの目標グループ化されたターゲット(&:
通常は明示的なルールがある場合は区切り文字を使用)が、make
作成するレシピへの単一の呼び出しを通知することを説明します。みんな一度に一つずつではなく、その一つです。
したがって、パターンルールは次のようになります。
a.in a.out &:
echo BLANK > $@
...欲しいものと同等の代わりに:
a.in a.out :
echo BLANK > $@
私が知る限り、後者のように動作し、一度に1つだけを生成するパターンルールを作成する方法はありません。あなたはただ持っていればいい分離%.in
そしてルール%.out
答え2
単一のルールに複数の暗黙的なターゲットを含めないでください。これがどこで言及されたのか覚えていませんが、そのような規則は確かに悪い習慣です。何が起こるかは次のとおりです。
$ cat Makefile
%.in %.out :
echo BLANK > $@
$ make -d a.in a.out
[... irrelevant output skipped ...]
Updating goal targets....
Considering target file 'a.in'.
File 'a.in' does not exist.
Looking for an implicit rule for 'a.in'.
Trying pattern rule with stem 'a'.
Found an implicit rule for 'a.in'.
Finished prerequisites of target file 'a.in'.
Must remake target 'a.in'.
echo BLANK > a.in
Successfully remade target file 'a.in'.
Considering target file 'a.out'.
File 'a.out' was considered already.
make: Nothing to be done for 'a.out'.
次の行を確認してください。
Considering target file 'a.out'.
File 'a.out' was considered already.
暗黙のターゲットは試みる前に「存在」しないため、ルールは複数のルールに「分割」されません。試行が行われ、a.in
一致が成功すると、他のすべての宛先は試行されたとマークされます。ほとんどの場合、これはあなたが望むものではありません。 2つのルールのみを作成してください。