2017年8月9日水曜日

暗黙ルールを駆使した Makefile の雛形

Makefile には知る人ぞ知る暗黙ルールがたくさんあるので,今回はそれを紹介したいと思う.

例えば,main.c というソースをコンパイルする Makefile を普通に書くと以下のような感じだが,
main:   main.o
    gcc -o $@ $<

main.o: main.c
    gcc -c -o $@ $<

実はこんなに長ったらしく書かなくても,ただ単に
main:   main.o

と書くだけで十分である.両者の実行結果はそれぞれ以下のようになる.(それぞれ上下が対応)
$ make
gcc -c -o main.o main.c
gcc -o main main.o
$ make
cc    -c -o main.o main.c
cc   main.o   -o main

gcc と cc の違いはあるものの,下側の例では依存関係も,コンパイルのコマンドも書かずに問題なくビルドできる.これは以下の Makefile の暗黙ルールに依るものだ.

【暗黙ルール1】
main.o が無いとき,同ディレクトリに,main.c があれば,cc で,main.cpp があれば g++ でコンパイルする.
ただし,変数 CC が指定されている場合,コンパイラには CC を用いる.

したがって,下側の Makefile を以下のように書き換えると,上側の Makefile と全く同じことができるようになる.
CC = gcc

main:   main.o

変数 CC のように,定義するだけでコンパイル時にオプションを自動で付けてくれたりする暗黙ルールがたくさんあり,それらをまとめて使用して Makefile を書くと,見やすく,かつミスの少ない Makefile を書くことができる.

個人的に最終形と言える Makefile の雛形を以下に示す.
PROG = SamleProg
SRCS = $(PROG).c\
       sample01.c\
       sample02.c\
       sample03.c
OBJS = $(SRCS:%.c=%.o)
DEPS = $(SRCS:%.c=%.d)

CC      = gcc
CFLAGS  = -g -Wall -Wextra -MP -MMD -I.
LDFLAGS = -lm

.PHONY:    all

all:       $(PROG)

$(PROG):   $(OBJS)

-include $(DEPS)

.PHONY:    clean

clean:
    $(RM) $(PROG) $(OBJS) $(DEPS)

ソースファイルが増えたら,sample03.c の下にどんどん追加していくだけで,正確にビルドできるようになっていくので,とても便利だ.これを make 及び make clean すると,それぞれ以下のようになる.

$ make
gcc -Wall -Wextra -MP -MMD -I.   -c -o main.o main.c
gcc -Wall -Wextra -MP -MMD -I.   -c -o sample01.o sample01.c
gcc -Wall -Wextra -MP -MMD -I.   -c -o sample02.o sample02.c
gcc -Wall -Wextra -MP -MMD -I.   -c -o sample03.o sample03.c
gcc -lm main.o sample01.o sample02.o sample03.o   -o main
$ make clean
rm -r main main.o sample01.o sample02.o sample03.o main.d sample01.d sample02.d sample03.d

各変数や,コンパイルオプションの意味は,ググればいくらでも解説しているページが見つかるので,ここでは割愛する.

大事なのは,それらを理解したあとで使用する上の Makefile のテンプレートだ!


0 件のコメント:

コメントを投稿