本文へスキップ
BecomeCoder

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

複数ファイルのビルド ― .o を経由する

ブラウザで完結

導入

cc -o app main.c utils.c のように一発でビルドもできますが、ファイルが増えると「1つ直しただけで全部を再コンパイル」になってしまいます。そこで各ソースを個別に .o へコンパイルし、最後にまとめてリンクします。こうすると make が「変わった .c.o だけ」を作り直せます。

説明

3つのルールに分けます。

app: main.o utils.o
	cc -o app main.o utils.o

main.o: main.c
	cc -c main.c

utils.o: utils.c
	cc -c utils.c

依存関係は木構造になります。

flowchart TD
  APP["app(実行ファイル)"] --> MO["main.o"]
  APP --> UO["utils.o"]
  MO --> MC["main.c"]
  UO --> UC["utils.c"]

make は木の葉から順にたどります。app を作るには main.outils.o が要る → それぞれ main.c / utils.c から cc -c で作る → そろったら cc -o app でリンク。cc -c main.c はコンパイルだけして main.o を作るコマンドです。

やってみよう

make を実行して、main.outils.oapp の順にコマンドが走るのを見ましょう。次に touch utils.c してから makeutils.oapp だけが作り直され、main.o は作り直されないことを確認してください。これが分割コンパイルの効き目です。

演習

一度 make してビルドしたあと、touch main.c してから再度 make してください。main.oapp が作り直され、utils.o は作り直されないことを確かめましょう。

ヒント1を見る

touch main.cmain.c を「新しく」します。main.omain.c に依存しているので作り直されます。

ヒント2を見る

utils.c は変えていないので、utils.o は「最新の状態」で作り直されません。

実際に動かしてみよう

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

Makefile + make(シミュレート)

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