久々にMakefileを使って、ちゃんとビルドさせようとしている。
何度やっても慣れないMakefileだ。。。
Makefileに慣れていないので、ほどほどに応用が利きそうなMakefileのテンプレートを作っておき、それをコピーして使い回している。
automakeなんかもやろうとしたけど、うーん、よくわからんかったのだ。
今は、Nordicのプロジェクトに入っていたMakefileを改造して使っている。
私が見てきたMakefileでは、コンパイルする対象の書き方が2パターンあった。
- オブジェクトファイル名(.o)を列挙して、コンパイル時に.c/.cppに変換
- ソースファイル名(.c, .cpp)を列挙して、target指定用は.oに変換
この辺は、オブジェクトファイルの置き場所や、Makefileを分散して書くかどうかというのと関係しそうな感じはする。
私は、オブジェクトファイルは1箇所にまとめて、Makefileも1ファイルで済ませたい。
ただ、ソースファイルはディレクトリごとに分かれていたりするので、ディレクトリを含めてソースファイル名を書いている。
NordicのMakefileもそうなっていたので、私のよりも出来が良いから使わせてもらっている。
構成は、こういう風になっている。
- OBJECT_DIRECTORY : オブジェクトファイル置き場
- TARGET_SRC : ビルド対象のソースファイルたち
- OBJECTS : オブジェクトファイル名たち
TARGET_SRCは自分で記入し、OBJECTSは変換して作るようになっている。
SRC_FILE_NAMES = $(notdir $(TARGET_SRC))
OBJECTS = $(addprefix $(OBJECT_DIRECTORY)/, $(SRC_FILE_NAMES:.cpp=.o) )
もちろん、ビルドなんかは普通に動作する。
で、ここからが本題だ。
参考にしたMakefileは、依存関係を自動生成するようになっていなかった。
だから、ヘッダファイルを変更してもビルドしてくれず、cleanしてmakeしなおしていた。
こういうときは、makedependか、-MMとかだったな、と思って過去Makefileを探したところ、こういうのが見つかった。
.Depend:
$(CXX) $(CXXFLAGS) -MM $(SRCS) > .Dependinclude .Depend
ああこれこれ、と名前だけ変更して追加したのだが、動作が変わらない。
.Dependファイルを見ると、依存するファイル名の方はソースファイルやヘッダファイルにパス名が入っているものの、最初に各オブジェクト名(依存されている方だから、被依存?)の方はオブジェクト名が載っているだけで、OBJECT_DIRECTORYの場所になっていないのだ。
探すと、出てきた。
GCC makefile dependency generation path - Stack Overflow
-MTに続けてパス付きでオブジェクトファイル名を書いておけば、それがそのまま載ってくるようだ。
書き方の例もあったので、foreachするやつを作った。
が、全然効かない。
.Dependファイルは、ちゃんとパス付きでオブジェクトファイル名が載っているし、lsで見てもオブジェクトファイルは存在する。
なぜだ。。
もう一度.Dependを見てみると、オブジェクトファイル名は「obj/./test.o」のように、1つカレントディレクトリが挟まっていた。
これは、ソースファイルが「$(XX)/test.c」のように、ディレクトリ名が変数になっていて、それがカレントディレクトリなので「XX=.」としたからだった。
試しに外して「obj/test.o」の形式に書き直すと、効いた。
そうか、そういうしくみだったのか。
今回はBash on Windowsなので、その影響もあるかもしれんが、気をつけておこう。
0 件のコメント:
コメントを投稿
コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。
注: コメントを投稿できるのは、このブログのメンバーだけです。