パーセントとアスタリスク(星)のメイクファイルの前提条件の違いは何ですか

パーセントとアスタリスク(星)のメイクファイルの前提条件の違いは何ですか

%.txt一部の Makefile には の前提条件があり、他の Makefile には がある理由を理解しようとしています*.txt

このフォルダレイアウトを作成しました。

$ tree .
.
├── hi1.txt
├── hi2.txt
├── hi3.txt
└── Makefile

まず、これを試してみました。

foo.txt: *.txt
    echo $^

そして期待通りの結果が出ました。

$ make
echo hi1.txt hi2.txt hi3.txt
hi1.txt hi2.txt hi3.txt

%.txtしかし、その後、いくつかの Makefile がワイルドカードとして使用されているのを見ました。そこで、次にそれを試してみました。

foo.txt: %.txt
    echo $^

ただし、これによりエラーが発生します。

$ make
make: *** No rule to make target '%.txt', needed by 'foo.txt'.  Stop.

なぜこのようなことが起こるのか誰か説明できますか?

GNU メイク 4.3

答え1

ではmake、パーセント記号はパターン マッチングに使用され、ターゲットに 1 つ、前提条件に (少なくとも) 1 つ必要です。

%.o: %.c
        $(CC) $(CFLAGS) -c -o $@ $<

このmakefileでは、ファイル名が で終わるものをビルドするためには、同じプレフィックスを持ち、ではなく.oで終わるファイルが必要であることを指定します。.c.o

これらのルールを構築するには、当然のことながら、ターゲットと前提条件を参照できる必要があります。ここで、変数$@$<変数が役立ちます。$@は「このルールのターゲット」を意味し、 は$<「このルールの最初の前提条件」を意味します。全て前提条件(実行可能ファイルをリンクするなど)が必要な場合は、変数を使用できます$^

%: %.o lib.o
        $(CC) $(LDFLAGS) -o $@ $^

上記の 2 つの例の makefile スニペットを 1 つの makefile に結合し、同じディレクトリ内の複数の C プログラムで使用する共通コードを含むファイル 'lib.c' がある場合は、任意のランダム.cファイル (たとえば )を追加して、 makefile に変更を加えずにのコードもリンクするfoo.cプログラムにコンパイルできます。foolib.c

前提条件が異なる限り、同じターゲットを持つパターンを使用することもできることに注意してください。たとえば、次のパターンは機能します。

%.o: %.c
        $(CC).....
%.o: %.cpp
        $(CXX).....

つまり、このディレクトリに C ソース ファイルと同じ名前 (拡張子なし) を持つ C++ ソース ファイルが存在しない限り、期待どおりに動作します。その場合、C++ バージョンは無視され、代わりに C ソースがコンパイルされます (C ルールが makefile の最初にリストされているため)。

詳細については、関連セクションGNU make マニュアルに記載されています。

関連情報