make コマンドの詳しい説明


make コマンドは、ユーザが 指定したスクリプトを実行するものです。しかし、 たんにスクリプトを実行するだけでなく、実行の必要性についても ある程度の検査を行ってくれます。 つまり、明らかに不要と思われる操作は実行しないのです。

これらのことを make コマンドに適切に伝えるために、Makefile と呼ばれるファイルを作成し、プログラムに関する各種の情報を提供します。 Makefile に記述する情報は、依存関係を指定する部分と、 プログラムを作成するための処理を指定する部分とに大別されます。

前者は、作成されるもの(「ターゲット」と呼ばれる)が 他のどのようなファイルから作成されるのかを指定するもので、 ターゲットのファイル名の後ろにコロン(:) を書き、 それに続けて依存するファイル名を並べて記述します。 後者は「インストラクション」と呼ばれ、ターゲットが どのようにして作成されるのかをコマンド行で入力する 形で記述します。つまり

ターゲット  :依存するファイル群
            インストラクション
という形式で指定します。

make コマンドは、与えられたこれらの情報を使って

最初に指定されたターゲット

を作成するために必要最小限の処理をしてくれるのです。


コマンド再実行の条件

UNIX では、ファイルを最後に更新した時刻 (最終更新時刻)がファイルシステムに保存されています。 make コマンドは、 関連するファイルの最終更新時刻をとりだし、 その時刻を比較してコマンドを実行するかどうかを判断するのです。

ここまでの話ををまとめると、make コマンドには大きく2つの 機能があります。

  1. プログラムの作成に必要な指定された処理を実行する
  2. ファイルの最終更新時刻を参照し、不要な処理の実行は避ける

処理を実行する必要があるのは

の2つの場合です。

マクロ機能

Makefile を簡単に記述するために、Makefile の中で 変数のように利用できるマクロ機能を使います。

マクロ機能を使うためには、まずマクロを定義しなくてはなりません。 マクロ定義は、 Makefile 中の任意の場所で

マクロ名=マクロの値
という形式で指定します。たとえば、オブジェクト・ファイルのならびを マクロとして指定するためには Makefile 中に次のような行を記述しておきます。
OBJS = main.o sub.o
なお、マクロ名は行頭に書くようにしてください。 ここではマクロ名として OBJS を指定し、 マクロの値としては main.o と sub.o を指定しています。

マクロ名は英数字や記号の一部が使えますが、 大文字の英字ではじめ、大文字の英字、数字、あるいは下線 (_) のいずれかを使うようにしてください。

まず、大文字を使う理由を説明しておきましょう。

Makefile では依存関係を指定するために 行頭にファイル名(ターゲット)が記述されます。 一方、マクロ名も行頭に書かれるので、紛らわしいのです。 一般にファイル名は小文字で表現されますから、マクロ名を大文字にしておけば、 ファイル名とマクロ名が区別しやすくなります。

また、先頭の文字に続けるものは大文字の他に数字と下線だけ、と断ったのは、 別な解釈をされる記号も存在するためです。 通常は、この規則にしたがってマクロ名を定義しても充分に用は足りるはずです。

次に、マクロの値です。 等号(=) の直後から行末までが値と見なされます。 この部分に空白文字が含まれていても、そのまま値として認識されます。 1行で書ききれないときは、行末に逆スラッシュ (\) を つければ複数行をそのマクロの値にすることもできます。

マクロの値を使うには、マクロ名を括弧(())や中括弧({})でくくり、 その前にドル記号($) をつけます。 これにはちょっと楽をする方法があり、 マクロ名が1文字の場合にかぎり、括弧でくくらなくてもよいことになっています。

マクロ定義は Makefile のどこに置いてもかまいません。しかし、 Makefile の読みやすさを考えて、 先頭の方でマクロ定義を行っておいた方がよいでしょう。


マクロの展開

オブジェクトファイルを OBJS というマクロに設定し、 ソースファイルを SRCS というマクロに設定するとします。

たとえばソースファイルが .c で、対応するオブジェクトファイルが .o で終わっているというように、相違点がサフィックス(ファイル名の 拡張子)だけの場合、多数のファイルについて同様の記述をしなくては ならないのは面倒です。

このようなとき、サフィックスの部分だけを変換するマクロの参照方法が あるのです。たとえば

SRCS = main.c sub.c
OBJS = $(SRCS:.c=.o)
と指定すると、SRCSのそれぞれの要素の .c という部分が .o に 変換され、 OBJS に設定されます。つまり、この定義では OBJS として main.o sub.o という値を指定したことに なるのです。

ためしに .c という部分を持たないもの (defs.hなど) を SRCS に設定すると、この値はそのまま OBJS に渡されます。

つまり、元になるマクロの等号の前にマッチした部分が等号の後ろに 書かれているものに置き換えられ、マッチしないものはそのままの 値になるのです。


既定義のマクロ

システムによってすでに定義されているマクロも存在します。
CC
通常、このマクロの値は cc で、 これを指定しておけば C コンパイラが使えます。
ユーザが自由に書き換えることもできます。
CFLAGS
コンパイル時のオプションが指定できるようになっています。
このマクロを定義している行がない場合は、 空文字列を値とするものとみなされます。

参考文献:UNIX MAGAZINE 1992.3 P.127- / 1992.4 P.109-


Takuya NISHIMOTO
Last modified: Tue Jan 7 10:54:21 1997