Makefile の憂鬱2007年01月18日 14時11分55秒

make(1) ユーティリティは、とても歴史が長い。古参 Make から、BSD 版やら GNU 版だけに留まらず、いくつもの派生拡張が存在する。Automake など、Makefile を生成するものから、makedepend などを含めるとそれこそ拡張の仕方と補助プログラムは多彩だ。

それなりにビルドツールが必要になるのだが、動作速度がそれなりに早く、依存関係を解決できる方法となると、やはり make を選ぶしか無い。特に VOS でも動くようにすると、シェルスクリプトなどの様に、プロセスを大量に生成するのは厳しい。Automake (正確には libtool だと思うが…)等が生成する Makefile は CPU の半分以上をプロセスの生成に使ってしまう。

古いツールなので仕方は無い。しかし、最近 Makefile の大変さは以下の様に書けないと事だと思うようになってきた。なお、この書式では、a.h を変更しても、aaa.pm が自動的に再構築されることは無い。


display Makefile
aaa.pm : aaa.obj
        bind $<
aaa.obj : aaa.c
        cc $<
aaa.c : aa.h
aa.h : a.h

蛇足だが、VOS 上で書かれているため、コマンドが少々 UNIX とは違う。

上の意図することを、正しい Makefile の書式で書いたのが以下の物である。


display Makefile
aaa.pm : aaa.obj
        bind $<
aaa.obj : aaa.c
        cc $<

aaa.obj : aa.h
aaa.obj : a.h

Makefile にはオブジェクトファイルがヘッダファイルに依存していると書かなくては動作はしない。

ソースファイルがヘッダファイルを取り込んでいるのだから、aaa.c: aa.h の方がより正しい依存関係を記述している。aaa.obj : aa.h は依存関係としては間違ってはいないが、ただの派生的な依存だ。aaa.obj: aaa.c が成り立ち、aaa.c : aa.h も成り立つ。それ故、aaa.obj: aa.h が成り立つと解釈してくれればと何度思ったことか。

この程度の依存関係だったら、それなりに解決できるが、何重もの依存関係が重なってくると、Makefile の為に依存関係の展開を何回とも繰り返すために必要以上にややこしくなる。

おまけに、実験に使ったファイルは以下の通り。


bash
% cat a.h
% cat aa.h
#include 
% cat aaa.c
#include 

int main()
{
}