本連載では、複数回に渡ってGNU makeで使うMakefileの基本的な機能の説明をしてきた。今回は、Makefileを複数のファイルに分割した場合のテクニックをもう少し取り上げておこう。どのやり方を採用するかはケース・バイ・ケースだが、さまざまなやり方があることを知っておくのは悪いことではないはずだ。
includeディレクティブでMakefileを分ける
前回は、1つのMakefileを複数のMakefileに分ける方法を取り上げた。分割したMakefileは同じディレクトリにある必要はなく、includeディレクティブでパスを指定すれば読み込むことができる。例えば、次のように大本となるMakefileの一部を「inc01.mk」と「inc02.mk」に分割したとする。
% tree
.
├── Makefile
└── mk
├── inc01.mk
└── inc02.mk
1 directory, 3 files
%
Makefieに次のようにincludeディレクティブを記述し、ほかのMakefileを読み込むようにする。
test: target1 target2
@echo "----"
@echo test:
@echo -n " pwd: "
@pwd
include mk/inc01.mk
include mk/inc02.mk
読み込まれる方のMakefile(mk/inc01.mk、mk/inc02.mk)の中身は次のようになっている。
◆mk/inc01.mk
target1:
@echo "--------"
@echo target1: mk/inc01.mk
@echo -n " pwd: "
@pwd
◆mk/inc02.mk
target2:
@echo "----"
@echo target2: mk/inc02.mk
@echo -n " pwd: "
@pwd
実行すると次のようになる。
%
make
--------
target1: mk/inc01.mk
pwd: /home/daichi/Documents
----
target2: mk/inc02.mk
pwd: /home/daichi/Documents
----
test:
pwd: /home/daichi/Documents
%
Makefileで利用する変数やターゲットなどは、行う処理が似ている場合はほぼ同じ記述を使うことがある。このように重複したコードが複数のファイルに存在する状態だと、場合によっては後で関連する全てのMakefileを書き換える必要な事態を生むことがある。
複数のMakefileを使っていて、どのMakefileにも似たような記述を行っている場合、それらを共通部分として取り出してまとめたいことがある。そんなときに使うのが、このincludeディレクティブであり、実用上は必須とも言える機能になっている。
問題はパスが変わる可能性があること
例えば、10個あるMakefileに共通する“似たような部分”を別のMakefileとして分割したとする。これをincludeディレクティブで読み込むようにすれば、共通部分の書き換えは1箇所で済むことになる(共通にしたことで、書き換えにより気を使うことになる面もあるのだが、ここではそちらの問題は置いておく)。
しかし、includeするところに書いてあるパスについてはハードコーディング状態だ。共有しているMakefileの配置場所を変えれば、そのMakefileをincludeしているほかの全てのMakefileの中に書いてあるパスを書き換える必要がある。逆に、呼び出しているMakefileのパスを変えても、絶対パスで記述してある場合を除いてincludeのところに書いてあるパスを書き換える必要がある。
完全に相対パスが変わらないという状況にある場合を除いて、includeに書いてあるパスは書き換えが必要な可能性がある。これは忘れたことに起きる事態なので、問題になりやすい。