法大奥山研究室

 previous  contents

付録 Makefile


 Makefile を使った makeコマンドによるコンパイルには,幾つかの利点があります。

ここでは,これらの利点を中心に,Makefile の作成方法を見ます。(Makefile の作成方法のすべてを知りたい方はマニュアルを参照ください。)

makeコマンド

make [options] [target]

ここでの options とは makeコマンドのオプションです。オプション一覧は,次のようすれば得られます。

% make -h

また,target とは,Makefile に記されたものです。その一般形式は次の通りです。

target: prerequisites
       command

これを「ルール」と呼びます。makeコマンドは,Makefile を探し,そこに記述されている targetcommand を実行します。command に指定するのは,UNIXのコマンドです。(Bシェルがそのまま使えます。)

 例えば,Makefile が次のようになっていたとしましょう。

# Makefile

sample: sample.c
       cc $^ -o $@

このルールの場合,targetsample で,それは $@ で参照できます。また,prerequisitessample.c で,それは $^ で参照できます。そして,commandcc $^ -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.cCC を「変数」と呼びます。変数は $() で参照することができます。例えば,

CC = cc

は変数 CC をコマンド cc に設定し,したがって,

LINK.c = $(CC) $(CFLAGS) $(CPPFLAGS) $(LDFLAGS) $(TARGET_ARCH)

$(CC) には cc が代入されます。コンパイルの対象となったファイルは sample.c でしたので,built-in での実行が

$(LINK.c) $^ $(LOADLIBES) $(LDLIBS) -o $@

です。デフォルトの設定では変数 CFLAGSCPPFLAGSLOADLIBES などが空なので,これは

cc $^ -o $@

という意味になります。したがって,Makefile が存在しないときに

% make sample

とすると,

cc     sample.c   -o sample

というコマンドが実行されます。

■設定の変更

上の CFLAGSCPPFLAGS などの変数は,make コマンドが予め意味を持った変数として設定しているものです。例えば,CFLAGScc のオプションを意味しています。そこで,次を書き込んだテキストファイルを 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)

CPPFLAGSRM はデフォルトの設定にあった変数です。デフォルトの設定にない変数は,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.cmyPrint.cmain.hmyPrint.h のいずれかが書き直されたとき,必要な部分のみを再コンパイルし,実行ファイルを生成してくれます。特に,myPrint.c はヘッダ main.h を読む込む設定になっているので,

myPrint.o: myPrint.c main.h

とすることで,myPrint.cmain.h に依存していることを教えることができます。したがって,main.h のみを書き換えると,myPrint.c のみを再コンパイルし,実行ファイルを生成し直します。

 上では,ターゲットに clean があります。

% make clean
rm -f main.o myPrint.o

ターゲットを指定することで,そのコマンドが実行されることは,prerequisites がなくとも同じです。


 previous  contents