一部のMakefileには前提条件があり、%.txt
他の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 $@ $<
このメイクファイルを使用してファイル名で終わるファイルをビルドするには、接頭辞は同じですが、次に終わる.o
ファイルが必要であることを指定します。.c
.o
これらのルールを構築するには、ターゲットと前提条件を参照できる必要があり、ここに変数が$@
必要$<
です。$@
「このルールの対象」を意味し、「$<
このルールについて最初にリストされた前提条件」を意味します。ビルドする必要がある場合は、次のコマンドを使用してください。みんな前提条件(例:実行可能ファイルの関連付け)を満たした次の変数を使用できます$^
。
%: %.o lib.o
$(CC) $(LDFLAGS) -o $@ $^
上記の2つの例のメイクファイルを単一のメイクファイルに結合し、同じディレクトリ内の複数のCプログラムで使用したい共通のコードを含む "lib.c"ファイルがある場合は、任意の.c
ファイルを追加できます。たとえば、makefileを変更せずにmakefileのコードにリンクされているfoo.c
プログラムにコンパイルします。foo
lib.c
前提条件が異なる限り、同じ目標を有するパターンを有することも可能である。たとえば、次のように動作します。
%.o: %.c
$(CC).....
%.o: %.cpp
$(CXX).....
つまり、このディレクトリにCソースファイルと同じ名前(拡張子なし)のC ++ソースファイルがない場合は、期待どおりに機能します。これが真であれば、C ++バージョンは無視され、Cソースコードがコンパイルされます(Cルールがmakefileに最初にリストされているため)。
詳細については、次を参照してください。関連部品GNU make マニュアルから。