2017/02/10

[c/c++]Makefileのdependは名前一致なのか

久々に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) > .Depend

include .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 件のコメント:

コメントを投稿

コメントありがとうございます。
スパムかもしれない、と私が思ったら、
申し訳ないですが勝手に削除することもあります。

注: コメントを投稿できるのは、このブログのメンバーだけです。