導入
ここまでの道具――変数・自動変数・パターンルール・関数・.PHONY――を全部組み合わせると、そのまま実プロジェクトに置ける「テンプレート Makefile」になります。最後に、その定番形を組み立てて動かしましょう。
説明
現場でよく見る形はこれです。
CC = cc
CFLAGS = -Wall -O2
TARGET = app
SRCS = $(wildcard *.c)
OBJS = $(SRCS:.c=.o)
$(TARGET): $(OBJS)
$(CC) $(CFLAGS) -o $@ $^
%.o: %.c
$(CC) $(CFLAGS) -c $< -o $@
clean:
rm -f $(TARGET) $(OBJS)
.PHONY: clean
読み解くと――先頭で設定(コンパイラ・オプション・成果物名・ソース/オブジェクト一覧)を変数にまとめ、本体はパターンルールと自動変数で汎用化、後片付けの clean を .PHONY で用意。ソースを足しても Makefile は無修正で、しかも差分ビルドが効く。これが make の完成形の1つです。
flowchart TD V["設定(CC / CFLAGS / SRCS / OBJS)"] --> T["$(TARGET): $(OBJS)"] T --> P["%.o: %.c(各 .o を生成)"] V --> C["clean(.PHONY)"]
やってみよう
make で一括ビルド → make(最新の状態)→ touch utils.c して make(utils.o と app だけ再ビルド)→ make clean(全部消える)→ make(また全部ビルド)。第1章から積み上げた仕組みが、この1枚の Makefile に全部入っていることを味わってください。仕上げに make -n で「何が走るか」も確認しておきましょう。
演習
このテンプレートで一度 make してビルドし、続けて make clean を実行して $(TARGET) と $(OBJS) がまとめて消えることを確認しましょう。
ヒント1を見る
clean のレシピ rm -f $(TARGET) $(OBJS) は、rm -f app main.o utils.o helper.o に展開されます。
ヒント2を見る
.PHONY: clean を付けておくと、clean という名前のファイルがあっても確実に動きます。