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
がなくとも同じです。