読者です 読者をやめる 読者になる 読者になる

ぬうぱんの備忘録

技術系のメモとかいろいろ

作った曲一覧はこちら

Makefileのヘッダファイルの依存関係のお話

C++ トラブルシューティング gcc

何があった

 Makefileのどのソースがそのヘッダに依存するとかの話があっていろいろ苦戦したのでメモ。

そもそも依存関係とは

 Makefileは、依存関係がズラーっと書いてあって、依存関係の末端にそのファイルの生成方法を書いておく、というのが基本的な考え方です。実際にはライブラリのリンク情報とかもいろいろアリますけどね。
 で、makeは"どのファイルが変更されたからどのソースをコンパイルし直そう"みたいなことをこの依存関係から解決します。ということは、この依存関係がきちんと書かれていないとファイルを更新したのに、再コンパイルされていないという事態に陥ってしまします。
 大抵は、all->オブジェクトファイル->ソースファイルという依存関係を省略ルールを駆使して書くと思うのですが、これだけだと不足で"どのソースがどのヘッダに依存しておくか"も書いておかないとマズイみたいなのです。当然といえば当然ではあるんですけど。
 で、いざヘッダファイルの依存関係を書こうと思うとこれがなかなか面倒。makeするときに勝手にやってくれないかな・・・。ということでこの記事のお題に至る訳です。

どうやって依存関係を自動生成するのか

 まずは依存関係を自動生成する方法です。これは簡単でgccに-MMDと-MPを付けるだけでいいみたいです。

  • -MMD:入力されたソースファイルからヘッダの依存関係を生成。システムヘッダは無視する。
  • -MP:依存ヘッダのダミーを生成.依存ヘッダが削除されてもエラーにならない。

 この2つのオプションによりコンパイル時に"hoge.d"な感じの依存ファイルが作成されます。この依存ファイルの中にどのソース(オブジェクトファイル)がどのヘッダに依存しているのか、とかが入っている訳です。

依存関係をどうやってMakefileに反映させるのか

 こっちはちょっと面倒?
Makefileの末尾でコンパイラの吐いた依存ファイルをインクルードするだけといえばそれまでなのだが、ソースファイルと同じ数だけの依存ファイルとかいっぱいあるやん・・・。でもコマンドで一発の様子

#コンパイルするソースファイルの一覧を用意
SRCS = hoge.cpp piyo.cpp
#拡張子を.cppから.dに置き換え
DEPENDS = $(patsubst %.cpp,%.d,$(SRCS))

...

#末尾で依存ファイルをまとめてインクルード
-include $(DEPENDS)

簡単っすね。ポイントは末尾のインクルードを"-include"とすること。"-include"だとファイルが存在しなくてもエラーにならない。なので、依存ファイルの存在しない初回makeがエラーにならない。
 ちなみに、このpatsubstを使うとオブジェクトファイル一覧も作れちゃうのでとっても便利

感想

 情報みつけるまでが大変だった・・・。
次はMakefile同士の依存関係をどうするかですかね。