make の使い方

概要
プログラムが複雑になると,いくつかの小さなプログラムに分けて編集・コンパイルした方が,作業効率がよくなる.しかし,コンパイルのたびに更新があったファイルを探すことは面倒だし,間違ってコンパイルし忘れる可能性もある.こういう場合には,更新があったファイルだけを自動でコンパイルし,実行ファイルを生成するプログラム make を利用する.
目次

一般的には,作成されたCやC++のプログラムは gcc や g++ を使って,コンパイルすことができる.例えば

  % gcc -Wall -g -lm hoge.c -o hoge

を実行すると,作成した hoge.c プログラムは hoge という実行可能なファイルにコンパイルすることが可能である.簡単なプログラムにたいして, gcc/g++ を利用することはできるが,プログラムが大きくなると,引数の設定などが多くなり, gcc/g++ だけを利用すると不便となる.再コンパイルときに,コンパイル必要となるファイルを探すのも不便である.ここで,一般的には Makefile を作成し, make コマンドを利用する.

make ユーティリティの目的は大きなプログラムの中の再コンパイルする必要がある部分を自動的に決定し,再コンパイルのためのコマンドを実行することである. make は,シェルコマンドからコンパイラを起動できるどうなプログラム言語とでも組み合わせて使用できる.実際 make の利用対象はプログラムだけに限られない.例えば, TeX ファイルのコンパイルもmakeを利用することができる.

make を使う準備をするためには,まず makefile と呼ばれるファイルを書かなければならない.このファイルは,プログラムを構成するファイル間の関係と各ファイルを更新するためのプログラムを記述したものである.プログラムの場合は普通,実行ファイルはオブジェクトファイルによって更新され,このオブジェクトファイルもまたソースファイルのコンパイルによって生成される.

適切な makefile さえあれば,ソースファイルを一部変更する度に

  % make

という簡単なシェルコマンドを実行するだけで,必要な再コンパイルが全て行われる. make プログラムは, makefile データベースとファイルの最終更新時刻を用いて,更新する必要があるファイルを見つける.このようなファイルに対して, make はMakefileに記録されているコマンドを実行する.

Makefile

makefileは以下のような"ルール"から成り立っている

  マクロ名 =1 [2 ...]
  ターゲット ... : 依存関係のファイル ...
        コマンド
  • マクロ名(変数)は一度定義した文字列を後の複数の場所で代用できる。マクロ名の定義によりMakefileの定義と編集を簡単になり,Makefileの解読も簡単になる。複数の値の間にスペースでわけ,長いラインはバックスラッシュ(\)で二つのラインに分割する。マクロ名の引用は"$(マクロ名)"と書く。
  • ターゲットは通常,プログラムによって生成されたファイルの名前であるが,"clean"のように実行するアクションの名前でも構わない。 ターゲットの中にはサフィックスルールという特別なターゲットがある(例えば.c.o)。生成コマンドを書く際に,いちいち何度も同じようなものを書くのは 面倒くさい。たとえば C のソースファイル「.c」からは必ずいつも オブジェクトファイル「.o」を作るので,依存ファイルのサフィックスが「.c」で,ターゲットのサフィックスが「.o」だったら自動的にある 生成コマンドを適用してほしい。この 「あるサフィックスに反応して,自動的に生成コマンドを適用するルール」がサフィックスルールである。このサフィックスルールを一度書いておけば, あとはそれが適用される依存関係には生成コマンドを省略できる。しかし,これは依存関係そのものを代用するものではない。依存関係自体は省略できない。
  • 依存関係は作成するターゲットを入力するのに利用されるファイルである。一つのターゲットはよくいくつかのファイルに依存している。
  • コマンドは実行するアクションのことである。複数のコマンドを持つ場合は一行ずつ記述する。 [注意]コマンド行の始まりは必ずタブでなければいけない!

簡単なMakefile例

以下の例は実行可能ファイルhogeが二つのオブジェクトファイル(.oファイル)に依存し,それから二つのCソースファイル(.hogesource1.cとhogesource2.c)と一つのヘッダファイル(hoge.h)に依存するという事例について記述するMakefileである。

  # マクロ定義部
  CC= gcc
  PROG=hoge # 生成する実行可能ファイル名
  LIBS= -lm # ライブラリ
  SRC= hogesource1.c hogesource2.c # ソースファイルリスト
  HEAD= hoge.h                     # ヘーダファイルリスト
  OBJ= $(SRC:.c=.o)                # 中間ファイルリスト(ソースファイル名の.cの部分を.oに変換)
  # 生成ルール定義部
  $(PROG): $(OBJ) $(HEAD)              # 依存関係を記述。':'の後は依存するファイルを記述する
  	$(CC) $(CFLAG) $(LIBS) $(OBJ) -o $(PROG)
  $(OBJ): $(HEAD)                  # 中間ファイルの依存関係
  .c.o:                            # サフィックスルール。「0.c」から「0.o」を生成
  	$(CC) $(INCS) -c $<        # 中間ファイル('.o'ファイル)の作成ルール
  clean:                           # 全てのオブジェクトファイルをディレクトリから削除
  	rm -f *.o

このmakefileを利用して,"hoge"という実行可能ファイルを作るためには,このセールコマンドを実行する。

  % make

最初からもう一回コンパイルするため全てのオブジェクトファイルをディレクトリから削除するのは定義した引数"clean"を利用する。

  % make clean

makeのMakefile処理

makeコマンドを実行すると,カレントディレクトリのmakefileを読み込む。デフォルトではmakeが一番最初のターゲットから開始します(上の例では"$(PROG)"ターゲットから始まる)("."で始まるターゲットではない)。このターゲットのことをデフォルトゴールという。ターゲットのコマンドを処理する前に,依存するファイルをチェックする。依存ファイルが前回処理の後で編集された場合はまず依存ファイルの生成ルールにより生成する。全ての依存ファイルが揃ったら,ターゲットのコマンドを実行する。

上の例で一回目の実行はまず$(PROG)(=hoge)ターゲットから処理する。$(PROG)ターゲットは中間ファイル$(OBJ)(=hogesource1.o hogesource2.o)とヘッダファイル$(HEAD)(=hoge.h)に依存する。$(OBJ)で定義された中間ファイルが存在していないため,まず".c.o"ターゲットで定義したコマンドで$(OBJ)を生成する。全ての中間ファイルを生成された後で,$(PROG)ターゲットに戻って,$(PROG)ターゲットのコマンドにより$(PROG)(実行可能ファイルhoge)を生成する。

二回目以降,依存関係により編集があるファイルのみにたいして必要なコマンドだけを実行する。例えばhogesource1.cファイルが編集した場合は,まず.c.oターゲットによりhogesource1.oを生成する。hogesource2.oとhoge.hが編集されてないので,hogesource2.oを再生成しないまま,直接にデフォルトゴール$(PROG)で定義した実行可能ファイルhogeを生成する。一方,hoge.hファイルが編集された場合は,"$(OBJ)"の依存関係によりhogesource1.oとhogesource2.o両方とも再生成する。

  % make clean

コマンドを実行する場合は,直接に"clean"ターゲットの依存関係のみチェックし,ターゲットのコマンドを実行する。例の場合はこのコマンドを実行すると,カレントディレクトリ内の全ての中間ファイルを削除する。同じくhogesource2.oファイルのみ生成したい場合は以下のコマンドを使えばいい。

  % make hogesource2.o

参考

課題

TeXファイルからpdfファイルを生成するMakefileを作ってみてください。


トップ   編集 凍結 差分 バックアップ 添付 複製 名前変更 リロード   新規 一覧 単語検索 最終更新   ヘルプ   最終更新のRSS
Last-modified: 2013-02-12 (火) 13:32:21 (1983d)