暗黙ルールを使って次のように書くのがよい.
.c.o: $(CC) $(CFLAGS) -c $< -o $@ main.o: main.c sub.h sub.o: sub.c sub.h
暗黙ルールには,拡張子ルール(suffix rule)とパターンルール(pattern rule)がある.
上記の.c.o
のようなのが拡張子ルール.
%
を使って各ルールをパターンルールというが,
gmake拡張機能なので,古いmakeでは使えない.
特に必要がないのであれば,互換性の面から古いmakeで使える機能範囲のみを使ってMakefileをかいておくのが望ましい.
次のようにかくと..o
,.c
をサフィックスとして登録することができる.
.SUFFIXES: .o .c
この指定は,標準の.SUFFIXES
に.o
と.c
を追加する動作になることに注意しよう.
標準のサフィックスをクリアしてから登録したい場合は,次のようにする.
.SUFFIXES: .SUFFIXES: .o .c
このテクニックは,例えばfoo.cに対してfoo.oを作りたいのだが, foo.oを逆アセンブルして作成したfoo.sがカレントディレクトリにあり, .cから.oを作るのか,.sから.oを作るのか紛らわしい場合に,ルールを整理するのに使える. ただ,通常は既定義のものが常識的な動作をするように設定されているので,あまり必要ではないはず.
.SUFFIXES: .SUFFIXES: .o .c .s
前に書いてあるほうが優先になる. 普通はこの順なんだと覚えておけばいい.
makeの標準のサフィックスリストはSUFFIXESマクロに記録されているので, 最も優先順位が高い側に拡張子を追加したい場合は,次のようにかけばよい.
.SUFFIXES: .SUFFIXES: .so $(SUFFIXES)
.c.oのようなサフィックスルールをダブルサフィックスルールという. これに対して,.cのようなものをシングルサフィックスルールという.
.c: $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
※$^
はgmake拡張機能.
.PRECIOUS
make中に中間ファイルが生成される場合,makeが終了すると削除される. 例えば,parse.oを生成するのに,parse.y→parse.c→parse.oという順で生成した場合, parse.cは中間ファイルであり,最終的には不要なものであると解釈されて削除される. 中間ファイルが削除されないようにするには,次のようにかいておけばよい.
.PRECIOUS: parse.c
あるいは, 次のようにMakefileにparse.cが明示的に登場するようにしておけば, 中間ファイルであっても消去されなくなる.
parse.c: parse.y
.SECONDARY: parse.c
.INTERMEDIATE: parse.c
%: %.c $(CC) $(CFLAGS) $(LDFLAGS) $^ $(LDLIBS) -o $@
%が一致した文字列のことをステム(stem)と呼ぶ. パターンルールは,実は/が含まれると,えらいややこしい動作になることがある(/を特別視しない仕様のため). したがって,サブディレクトリを含むビルドを行うMakefileを書く場合にはこれに留意して慎重に設計しないといけない.
.PHONY
.PHONY: clean
makeによって生成したファイル群を削除して,もとのクリーンな状態にもどすために
clean
という擬似ターゲットを用意しておくことが慣例になっている.
これにより,
ユーザはmake clean
を実行することで,プロジェクトを初期状態にもどすことができるようになる.
ここで,
何らかの表紙に偶然cleanという実ファイルができてしまった場合,make cleanが正しく動作しなくなる.
こういった問題を防ぐために,clean
が擬似ターゲットであることを明示しておくのがよい.
記号 | 使用例 | 説明 |
---|---|---|
- | -rm -f *.o |
コマンド実行中に発生するエラーを無視してmakeを継続する. |
+ | +$(YACC) -f $< |
make -nでお試し実行のときも実行するようにする. |
@ | @echo Linking | 実行するコマンド文字列を表示しないようにする. |
make -i
.IGNORE:
.DELETE_ON_ERROR: