%.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
プログラムにコンパイルできます。foo
lib.c
前提条件が異なる限り、同じターゲットを持つパターンを使用することもできることに注意してください。たとえば、次のパターンは機能します。
%.o: %.c
$(CC).....
%.o: %.cpp
$(CXX).....
つまり、このディレクトリに C ソース ファイルと同じ名前 (拡張子なし) を持つ C++ ソース ファイルが存在しない限り、期待どおりに動作します。その場合、C++ バージョンは無視され、代わりに C ソースがコンパイルされます (C ルールが makefile の最初にリストされているため)。
詳細については、関連セクションGNU make マニュアルに記載されています。