gnumakeで「このファイル」__FILE__を実装する
多くのプログラミング言語が「このファイル」を変数__FILE__で教えてくれる。__FILE__を参照したコードを含むソースファイルのパスが返ってくる。この便利な機能はgnumakeにない。しかし、MAKEFILE_LISTという変数から現ファイルを推測できる。
config.mkに
THIS_FILE=$(filter %config.mk,$(MAKEFILE_LIST))
とするとTHIS_FILEがconfig.mkのパスを値として持つことになる。ただし、「config.mk」が唯一この名をもつMakefileであることを前提とする。
このハックを発見していい気になっていたら、JGCがすでに丁寧に解説しているのを発見:
http://blog.jgc.org/2007/01/what-makefile-am-i-in.html
どうやらMAKEFILE_LISTの最後の値が現makefileになるらしい。つまり上記のfilterが無用ってことになる。さらにコメントにgmake 3.81以降だとlastwordが使える、と改善案が。つまりこれが、__FILE__として使えることになる:
$(lastword $(MAKEFILE_LIST))
プロジェクトのルートディレクトリのconfig.mkやらinclude.mkにこれを入れておけばどこからincludeしても常にプロジェクトルートを参照できることになる。
PROJECT_ROOT=$(abspath $(dir $(lastword $(MAKEFILE_LIST))))
これにより次のようgnumakeによるプロジェクト構成が可能になる:
- 各サブディレクトリはconfig.mkをincludeする
- config.mkは上記の方法でPROJECT_ROOTをexportする
- サブディレクトリのMakefileはPROJECT_ROOT下のリソースを参照することができる。
- virtualenvとか: $(PROJECT_ROOT)/virtualenv/bin/python foo.py
- binに入れてあるコマンドとか: $(PROJECT_ROOT)/bin/my-build-util.py