makefile に於ける依存関係

Makeの依存関係を生成する方法には,色々選択肢がある.

手っ取り早いのは

depend:
      makedepend -Y -- $(CPPFLAGS) -- *.cc  

Makefileに書いておいて,

$ make depend

とすることで Makefile自身に依存関係を自動で記入する方法.

しかし,この方法には以下の二つの問題がある.

  • make depend を実行しないと,依存関係は更新されない
  • 依存関係がそのままMakefileに含まれている.(これは,cvssvnMakefile を共有するとき,とてつもなく不便になる).

後者の問題は,つぎのようにすることで解決できる.

depend:
      makedepend -f- -Y -- $(CPPFLAGS) -- *.cc  > .depends
-include .depends

ただし,これでも 前者の問題は尚残されたまま.

この問題に対して make の info には,"Generating Prerequisites Automatically"という節が設けられている.この節では,

  • コンパイラの"-M"オプションで依存関係を一度 *.d というファイルにはく
  • include $(sources:.c=.d) てな感じで,Makefile から *.d をincludeする

ことでうまく解決する方法が紹介されている.

そこで,この方法をもう少し改良して *.d を 適当なディレクトリへ保存するルールを書いてみた.

DEPDIR=.deps
$(DEPDIR)/%.d: %.cc
        (rm -f $@; mkdir -p $(DEPDIR); \
        $(CXX) -MM $(CXXFLAGS) $< > $@.$$$$; \
        sed &#39;s,\($*\)\.o[ :]*,\1.o $@ : ,g&#39; < $@.$$$$ > $@; \
        [ -s $@ ] || rm -f $@; rm -f $@.$$$$; )
$(DEPDIR)/%.d: %.c
        (rm -f $@; mkdir -p $(DEPDIR); \
        $(CC) -MM $(CFLAGS) $< > $@.$$$$; \
        sed &#39;s,\($*\)\.o[ :]*,\1.o $@ : ,g&#39; < $@.$$$$ > $@; \
        [ -s $@ ] || rm -f $@; rm -f $@.$$$$; )
include  $(OBJS:%.o=$(DEPDIR)/%.d)

これは,すんごい便利.