Makefileの自動生成
この記事の内容は古くなっています。
をどうぞ
久々に、というか初めて本格的にC++を使ってプログラムを書いているのだが、Makefileを書くのが面倒で仕方ない。C++で依存関係といえば#include。つまり#include行を取り出してMakefileにぶち込むスクリプトを書けばいいわけだ。しかしここで変なバグを作って混乱するのも馬鹿らしい。
だからコンパイラに任せてしまおう。
参考にしたのは以下のページ。GNU Makeのマニュアルの日本語訳。
GNU Make 再コンパイル作業を制御するプログラム
gccでは、
gcc -MM hoge.cpp
とすれば、cppファイルを解析して、依存しているヘッダファイルを自動的に取り出してくれる。
これを使えば以下の手順でMakefileを自動生成できる。
ところで、.dependもソースやヘッダファイルに依存している。ソースコードに新しく#includeを追加すれば依存関係が変わるのだから当然だろう。
ゆえに、このファイルもMakefileによって必要に応じて生成し直さないといけない。
そのために、.dependファイルも.oファイルと同じものに依存させればよい。
具体的には
$ gcc -MM hoge.cpp
hoge.o : hoge.cpp hoge.hpp foo.h bar.h
を、sedを使って
$ gcc -MM hoge.cpp | sed 's/\($*\)\.o[ :]*/\1.o hoge.depend : /g' hoge.o hoge.depend : hoge.cpp hoge.hpp foo.h bar.h
などとすればいい。
Makefileにすると以下のようになる。
PROGRAM := hoge SOURCES := $(wildcard *.cpp) OBJS := $(SOURCES:.cpp=.o) DEPENDS := $(SOURCES:.cpp=.depend) CXX := g++ CPPFLAGS := -O2 .PHONY: all all: $(PROGRAM) $(PROGRAM): $(OBJS) $(CXX) -o $(PROGRAM) $(CPPFLAGS) $^ %.depend: %.cpp @echo generating $@ @$(SHELL) -ec '$(CC) -MM $(CPPFLAGS) $< | sed "s/\($*\)\.o[ :]*/\1.o $@ : /g" > $@; [ -s $@ ] || rm -f $@' ifneq "$(MAKECMDGOALS)" "clean" -include $(DEPENDS) endif .PHONY : clean clean: rm -f $(PROGRAM) rm -fr $(OBJS) rm -fr $(DEPENDS)
これで当面、Makefileには触れなくてよさそうだ