ソフトウェア設計及び演習2017
Makefileの書き方
Makefileのごく簡単な解説
Makefileは,一見すると複雑ですが,ルールさえ分かれば構造は単純です.
Makefileの基本構造
(作りたいもの): (その元になる材料) __[TAB]__(実際の作り方) <-- 先頭が空白ではなくTAB
(作りたいもの) の後にコロン(:)を書き,続いて(その元になる材料)を記述します.
次の行に,先頭にTAB,続いて(実際の作り方)を記述します.
具体例
main.c,sub.cの二つのソースファイルから exe という実行バイナリを作成するには,
% gcc main.c sub.c -o exe
とすることは既に習っていると思いますが,これでは,どちらか一方のソースだけを修正した場合でも 両方をコンパイルし直さなければなりません.
したがって,普通は
% gcc -c main.c % gcc -c sub.c % gcc main.o sub.o -o exe
のように,別々にオブジェクトファイルを生成して,最後にリンクします.
さて,ソースファイルの数が増えてくると(例えば,20個とか),これらを手動で入力・管理していくことが面倒になります (し,間違いのもとにもなります).そこで,Makefileを利用します.
exe: main.o sub.o gcc -o exe main.o sub.o main.o: main.c gcc -c main.c sub.o: sub.c gcc -c sub.c
- gccの前はTABであることに注意しましょう.
makeコマンドは,
% make (作りたいもの)
として実行するのが基本ですが,(作りたいもの)を省略した場合には,一番最初の(作りたいもの)が作成されます.つまり,
% make
とすれば,exeを作成することになります.
この際,makeコマンドは,exeの元材料であるオブジェクトファイル(main.o と sub.o)を使って,gcc -o exe main.o sub.oを実行しようとします.
ただし,main.o,sub.o についても,それぞれMakefileに材料と作り方が記述されていますので,次のような順序で動作します.
- まず,main.oとmain.cのタイムスタンプを比較して,main.oの方が古ければ(main.cに編集が加えられていることになるので)gcc -c main.cを実行してmain.oを作り直します.もちろん,main.oが存在しないときも同様にコンパイルされます.
- sub.oとsub.cについても同様に動作します.(もしsub.cが編集されていなければ何も起こりません)
- このように,main.o,sub.oを最新に更新した上で,一番上のgcc -o exe main.o sub.oが実行され,exeが出来上がります.
以上のように,ある実行形式を作りたいとき,その材料がどれなのか,どうやって作るのか,といった「各ファイルの依存関係」を記述したものがMakefileです.
一般的な例
一般的なMakefileの例
CC = gcc CFLAGS = -O4 -Wall -I../include DEST = ~/bin LDFLAGS = -L../lib LIBS = -lm OBJS = main.o sub.o PROGRAM = exe all: $(PROGRAM) $(PROGRAM): $(OBJS) $(CC) $(OBJS) $(LDFLAGS) $(LIBS) -o $(PROGRAM) clean: rm -f *.o *~ $(PROGRAM) install: $(PROGRAM) install -s $(PROGRAM) $(DEST)
はじめの方の「○=○」という記述は,単に後で使う変数の定義です.
実行バイナリを作成する部分は以下です.基本に忠実に,作りたいもの,その元となる材料,実際の作り方が書かれているだけです.
$(PROGRAM): $(OBJS) $(CC) $(OBJS) $(LDFLAGS) $(LIBS) -o $(PROGRAM)
以下の部分は make install と実行したときにのみ,参照されます.若干変則的ですが,makeコマンドは「installの作成には材料$(PROGRAM)が必要で,実際の作り方は実行バイナリを所定のディレクトリにコピーすること」と解釈します.つまり,installというファイルは作成されませんが,installコマンドを実行した時点でmakeは終了します.
install: $(PROGRAM) install -s $(PROGRAM) $(DEST)
以下の部分も少々変則的です.作りたいもの(all)とその材料は示されてますが,実際の作り方が記述されていません.
all: $(PROGRAM)
allを作りたければ,まず$(PROGRAM)を作れ,という意味になります.
注意点
■先頭のTAB
(実際の作り方)は,必ずTABの後に書く必要があります.コピー&ペースト等でMakefileを作成すると,TABがスペースに置き換わってしまって動かない!というトラブルがよく起こります.注意しましょう.
■暗黙のルール
先ほどのMakefileには「main.cとsub.cから,それぞれmain.oとsub.oを作成する」ための方法が書かれていません.
このように,*.cから*.oを作成する手順は省略することも可能です.
ただし,コンパイル時には,最適化オプション-Oやインクルードファイルの所在を明示する-Iオプションが使われることが普通ですので,CFLAGSにその内容を定義しておきます.(*.cから*.oが自動作成される際には,CFLAGSをオプションとみなします)
最終更新日:2017/04/03 09:14:26