(GNU)Makefileの変数とマクロの置換

変数とマクロ置換をうまく使えば冗長なコードをまとめられるみたいだ(GNU Makefile)。

Makefile
|
+--> A/Makefile
|
+--> B/Makefile
|
+--> C/Makefile

このようにトップディレクトリにMakefileがあり、配下のA,B,CディレクトリのMakefileがある場合、なにも考えないと、

#
# Makefile
#
install:
	@make -C A install
	@make -C B install
	@make -C C install

と書いてしまう(この程度ならこれでもいいけど)が、以下のように書ける。

$ pwd
/home/foo/test
$ cat Makefile
#
# sample Makefile
# $Id$
NAMES=A B C

install: $(NAMES:%=install-%)

$(NAMES:%=install-%):
	@make -C $(@:install-%=%) install
$ cat A/Makefile
#
# sample Makefile in A directory
# $Id$
install:
	@echo "install of A directory."
$ cat B/Makefile 
#
# sample Makefile in B directory
# $Id$
install:
	@echo "install of B directory."
$ cat C/Makefile
#
# sample Makefile in C directory
# $Id$
install:
	@echo "install of C directory."
$ make install
make[1]: ディレクトリ `/home/foo/test/A' に入ります
install of A directory.
make[1]: ディレクトリ `/home/foo/test/A' から出ます
make[1]: ディレクトリ `/home/foo/test/B' に入ります
install of B directory.
make[1]: ディレクトリ `/home/foo/test/B' から出ます
make[1]: ディレクトリ `/home/foo/test/C' に入ります
install of C directory.
make[1]: ディレクトリ `/home/foo/test/C' から出ます
$ 

ちなみにカレントディレクトリのMakefile中の変数はマクロ置換により次のように展開しているはず。

install: install-A install-B install-C

install-A:
	@make -C A install
install-B:
	@make -C B install
install-C:
	@make -C C install

ここの例ではディレクトリが3つだけなのであまり有り難みを感じないが、ディレクトリが多ければ多いほど有り難い。