make 改訂版(5章) 続きの続き (6章)

ヘッダファイルで定義を変更した時に、オブジェクトをリコンパイルできるようにしておきたい
こういう場合は、オブジェクトファイルの依存関係にヘッダファイルを追加すれば問題は解決する。

でも、間違ったり漏れたりすることもあるので、自動的に作ってもらえると嬉しい。
gcc には "-M"っていうオプションがあって、こいつを使うと実現できる。
man によると、次のようなオプションだそうな。

プリプロセッサに対してmake で使用可能な、オブジェクト間の依存関係を記述した出力を生成するように指示します。

basic.mkという名前で次のような内容のMakefileのひな形を作っておけば、
make実行時に動的に依存関係を解消してくれちゃう。
(basic.mk)

OBJS = main.o hoge.o piyo.o
SRCS = ${OBJS:.o=.c}

main : ${FRC}
	${MAKE} ${CFLAGS} "FRC=${FRC}" makefile
	${MAKE} ${CFLAGS} "FRC=${FRC}" ${OBJS}
	${CC} -o $@ ${OBJS}

makefile : ${FRC}
	rm -f $@
	cp basic.mk $@
	echo "#Automatically generated dependencies lit:" >> $@
	${CC} ${CFLAGS} -M ${SRCS} >> $@
	chmod -w $@

${OBJS} : ${FRC}

force_rebuild:

clean :
	rm -f main *.o *~

こいつをmakeに食わせてコンパイルをすると

[kobakoba0723@fedora13-intel64 header]$ make -f basic.mk
make  "FRC=" makefile
make[1]: ディレクトリ `header' に入ります
make[1]: *** ターゲット `makefile' を make するルールがありません.  中止.
make[1]: ディレクトリ `header' から出ます
make: *** [main] エラー 2

ん!?、エラー!? なんだ?????
「ルールがありません」って、Makefileが指定されてないの??
(修正版basic.mk)

OBJS = main.o hoge.o piyo.o
SRCS = ${OBJS:.o=.c}

main : ${FRC}
	${MAKE} -f basic.mk ${CFLAGS} "FRC=${FRC}" makefile
	${MAKE} ${CFLAGS} "FRC=${FRC}" ${OBJS}
	${CC} -o $@ ${OBJS}

makefile : ${FRC}
	rm -f $@
	cp basic.mk $@
	echo "#Automatically generated dependencies lit:" >> $@
	${CC} ${CFLAGS} -M ${SRCS} >> $@
	chmod -w $@

${OBJS} : ${FRC}

force_rebuild:

clean :
	rm -f main *.o *~

これならどうだろう

[kobakoba0723@fedora13-intel64 header]$ make -f basic.mk
make -f basic.mk  "FRC=" makefile
make[1]: ディレクトリ `header' に入ります
rm -f makefile
cp basic.mk makefile
echo "#Automatically generated dependencies lit:" >> makefile
cc  -M main.c hoge.c piyo.c >> makefile
chmod -w makefile
make[1]: ディレクトリ `header' から出ます
make  "FRC=" main.o hoge.o piyo.o
make[1]: ディレクトリ `header' に入ります
cc    -c -o main.o main.c
cc    -c -o hoge.o hoge.c
cc    -c -o piyo.o piyo.c
make[1]: ディレクトリ `header' から出ます
cc -o main main.o hoge.o piyo.o

お、こんどは通ったぞ。
でも、${MAKE}ってコマンドラインを引き継ぐんじゃなかったっけか。
GNU make 日本語訳(Coop編) makeの再帰利用には、そんなようなことが書いてあるし、間違ってないよなぁ。

6章に『MAKEFLAGSマクロ』なんてすてきな名前のマクロがあるけど、-f/-p/-tはセットされないって書いてあるし、『-f basic.mk』はどこに行ったんだい?
ん〜、よくわからんなぁ。

とりあえず、おいといてヘッダファイルを編集した時とか明示的にリコンパイルしたい時には、FRC=force_rebuildをつけてコンパイルすればよい

[kobakoba0723@fedora13-intel64 header]$ make -f basic.mk FRC=force_rebuild
make -f basic.mk  "FRC=force_rebuild" makefile
make[1]: ディレクトリ `header' に入ります
rm -f makefile
cp basic.mk makefile
echo "#Automatically generated dependencies lit:" >> makefile
cc  -M main.c hoge.c piyo.c >> makefile
chmod -w makefile
make[1]: ディレクトリ `header' から出ます
make  "FRC=force_rebuild" main.o hoge.o piyo.o
make[1]: ディレクトリ `header' に入ります
rm -f makefile
cp basic.mk makefile
echo "#Automatically generated dependencies lit:" >> makefile
cc  -M main.c hoge.c piyo.c >> makefile
chmod -w makefile
make[1]: ディレクトリ `header' から出ます
make[1]: ディレクトリ `header' に入ります
rm -f makefile
(以下省略)

あら、これまたおかしい。。。なんでコンパイル終わった後に、makefile作り直してんの??
makeの実行コマンドが変なんかな?それともMakefile
にしても、延々Makefile作り直してんのは変だろう。。。
『-f basic.mk』がなにか悪さしてるだとしても、外すとそもそもmakeできないんだからどうしようもないよな、これ。