本文へスキップ
BecomeCoder

Makefile / makeコース · 第2章 実用的なビルド · レッスン8

自動変数 ― $@ $< $^

ブラウザで完結

導入

レシピの中で「ターゲット名」や「依存ファイル名」をもう一度手で書くのは面倒だし、書き間違いのもと。make には、ルールごとに中身が変わる自動変数が用意されています。これを使うとレシピがぐっと短く、汎用的になります。

説明

よく使う自動変数はこの3つです。

自動変数意味
$@ターゲット名
$<最初の依存ファイル
$^すべての依存ファイル(スペース区切り)

先ほどのビルドを自動変数で書き直します。

app: main.o utils.o
	cc -o $@ $^

main.o: main.c
	cc -c $< -o $@

utils.o: utils.c
	cc -c $< -o $@

app のルールでは $@app$^main.o utils.o に展開され、cc -o app main.o utils.o になります。main.o のルールでは $<main.c$@main.o なので cc -c main.c -o main.o。ルールごとに中身が自動で変わるのがポイントです。

もう1つ、$? は「ターゲットより新しい依存だけ」を表します。差分ビルドのログを出すときなどに便利です。

やってみよう

make して、各ルールで自動変数がどう展開されたかを見比べましょう。main.outils.o でレシピの文字列は同じなのに、展開後のコマンドが違うことに注目してください。この「同じ書き方で使い回せる」性質が、次章のパターンルールにつながります。

演習

app のリンクのレシピを、ファイル名を直書きせず cc -o $@ $^ の形にして、makecc -o app main.o utils.o が生成されるようにしましょう。

ヒント1を見る

$@ はターゲット(app)、$^ は依存すべて(main.o utils.o)に展開されます。

ヒント2を見る

main.o / utils.o 側のルールも cc -c $< -o $@ にしておくと、全体が自動変数で統一できます。

実際に動かしてみよう

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

Makefile + make(シミュレート)

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