Makefile を使った makeコマンドによるコンパイルには,幾つかの利点があります。
ここでは,これらの利点を中心に,Makefile の作成方法を見ます。(Makefile の作成方法のすべてを知りたい方はマニュアルを参照ください。)
■makeコマンド
make [options] [target]
ここでの options とは makeコマンドのオプションです。オプション一覧は,次のようすれば得られます。
% make -h
また,target とは,Makefile に記されたものです。その一般形式は次の通りです。
target: prerequisites
       command
これを「ルール」と呼びます。makeコマンドは,Makefile を探し,そこに記述されている target の command を実行します。command に指定するのは,UNIXのコマンドです。(Bシェルがそのまま使えます。)
例えば,Makefile が次のようになっていたとしましょう。
# Makefile
sample: sample.c
       cc $^ -o $@
このルールの場合,target は sample で,それは $@ で参照できます。また,prerequisites は sample.c で,それは $^ で参照できます。そして,command は cc $^ -o $@ です。
% make
あるいは
% make sample
とすれば,コマンド cc sample.c -o sample が実行されます。
■デフォルトの設定
Makefile がない場合に,
% make sample
とすれば,どうなるのでしょうか。実は,target $@ には sample が,prerequisites $^ には sample.c が代入され,デフォルトの設定での command を実行します。デフォルトの設定を確認しましょう。
% make -p
# GNU Make version 3.79, by Richard Stallman and Roland McGrath.
# Built for powerpc-apple-darwin7.0
# Copyright (C) 1988, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99
#       Free Software Foundation, Inc.
...
# default
LINK.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
# default
CC = cc
...
# default
RM = rm -f
...
# Not a target:
.c:
#  Implicit rule search has not been done.
#  Modification time never checked.
#  File has not been updated.
#  commands to execute (built-in):
        $(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
...
LINK.c や CC を「変数」と呼びます。変数は $() で参照することができます。例えば,
CC = cc
は変数 CC をコマンド cc に設定し,したがって,
LINK.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)
の $(CC) には cc が代入されます。コンパイルの対象となったファイルは sample.c でしたので,built-in での実行が
$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@
です。デフォルトの設定では変数 CFLAGS や CPPFLAGS,LOADLIBES などが空なので,これは
cc $^ -o $@
という意味になります。したがって,Makefile が存在しないときに
% make sample
とすると,
cc sample.c -o sample
というコマンドが実行されます。
■設定の変更
上の CFLAGS や CPPFLAGS などの変数は,make コマンドが予め意味を持った変数として設定しているものです。例えば,CFLAGS は cc のオプションを意味しています。そこで,次を書き込んだテキストファイルを Makefile として保存し,makeしてみましょう。
# Makefile CFLAGS = -O -Wall
実行例です。
% make sample cc -O -Wall sample.c -o sample %
Makefile に書き込んだ cc のオプションが付いているのが確認できます。
* "CPP" と言えば C++ ですが,make のマニュアルでは CPPFLAGS はコンパイラへの追加的オプション用であるとなっています。
■変数とファイルの依存性
デフォルトの設定にある変数以外の変数を作成することができます。次の例はソースファイルの分割(前頁)で見たプログラムに対する Makefile です。
# Makefile
CFLAGS = -O -Wall
CPPFLAGS = -c
OBJECTS = main.o myPrint.o
sample: $(OBJECTS)
        $(CC) $(CFLAGS) $^ -o $@
main.o: main.c myPrint.h
        $(CC) $(CFLAGS) $(CPPFLAGS) $< -o $@
myPrint.o: myPrint.c main.h
        $(CC) $(CFLAGS) $(CPPFLAGS) $< -o $@
clean:
        $(RM) $(OBJECTS)
CPPFLAGS や RM はデフォルトの設定にあった変数です。デフォルトの設定にない変数は,OBJECTS です。これにはオブジェクトファイルが指定してあります。各オブジェクトに対するルールがターゲット clean の前に記してあります。$< は prerequisites の一つ目を参照します。
% make cc -O -Wall -c main.c -o main.o cc -O -Wall -c myPrint.c -o myPrint.o cc -O -Wall main.o myPrint.o -o sample % ./sample Welcome! This is a test.
上の場合,main.c,myPrint.c,main.h,myPrint.h のいずれかが書き直されたとき,必要な部分のみを再コンパイルし,実行ファイルを生成してくれます。特に,myPrint.c はヘッダ main.h を読む込む設定になっているので,
myPrint.o: myPrint.c main.h
とすることで,myPrint.c が main.h に依存していることを教えることができます。したがって,main.h のみを書き換えると,myPrint.c のみを再コンパイルし,実行ファイルを生成し直します。
 上では,ターゲットに clean があります。
% make clean rm -f main.o myPrint.o
ターゲットを指定することで,そのコマンドが実行されることは,prerequisites がなくとも同じです。