本文へスキップ
BecomeCoder

Makefile / makeコース · 第3章 パターンとテクニック · レッスン12

仕上げ ― 実際に使える小さなMakefile

ブラウザで完結

導入

ここまでの道具――変数・自動変数・パターンルール・関数.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 して makeutils.oapp だけ再ビルド)→ 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 という名前のファイルがあっても確実に動きます。

実際に動かしてみよう

上のエディタが Makefile、下が端末です。Makefile を確かめたら端末に `make` と打って Enter を押すと、どのレシピがどの順で走るかが表示されます。`ls` で作業中のファイル(main.c などが最初から置いてあります)、`touch main.c` のあと `make` で差分ビルドの様子、`make -n` で「実行せず何が走るか」を確かめられます。各レッスンは毎回まっさらな状態から始まり、「最初からやり直す」でいつでも戻せます。

Makefile + make(シミュレート)

Makefile を書いて make を試せる学習用環境を読み込みます(本物のGNU Makeではなく、依存解決とタイムスタンプ再ビルドを再現した軽量な自作エンジンです)。
スクロールして表示された時点でも自動で読み込まれます。