続、Makefileの書き方再入門。簡潔なMakefile編
前回(Makefileの書き方スピード再入門 - フリーフォーム フリークアウト)の内容について、twitterで@makingさんに、pyopyopyoさんの素晴らしい記事について教えていただきました。
Twitter / making: .@cou929 make -pみてみるといいです。 ...
Makefile は簡潔に書きましょう - ぴょぴょぴょ? - Linuxとかプログラミングの覚え書き -
内容は、最大限にmakeビルトインのルールを活用して、極力シンプルなMakefileを書こうというものです。
デフォルトのルールの確認
Makefileがあるディレクトリで、make -p します。出力は結構大きいです。
簡潔な書き方の例
例えば、foo.cppをコンパイルして、fooというバイナリを作るときは、
all: foo
これだけで全てやってくれます。これはすごい。ソースコードが複数ファイルに分かれている場合でも、ルールを一行追加するだけでOKです。
foo: foo.o bar.o
コンパイラオプションを追加したり、パスが通っていない場所に作りかけの自前ライブラリがある場合などには、最小限のマクロだけ追加します。
CXXFLAGS += -Wall -I/foo/bar/include # cのプログラムの場合はCFLAGS LDFLAGS += -L/foo/bar/lib -lfoo
昨日の例を改善
Before
CC=g++ LIB= LIBDIR=-L/opt/local/lib INCDIR=-I/opt/local/include CFLAGS=-Wall TARGETS=foo SRCS=foo.cpp OBJS=$(SRCS:.cpp=.o) all: $(TARGETS) $(OBJS) $(TARGETS): $(OBJS) $(CC) $(LDFLAGS) -o $@ $(OBJS) $(INCDIR) $(LIBDIR) $(LIB) .cpp.o: $(CC) $(CFLAGS) -c $< $(INCDIR) $(LIBDIR) $(LIB) .PHONY: clean clean: $(RM) *~ $(TARGETS) $(OBJS)
After
TARGETS=foo CXXFLAGS += -Wall LDFLAGS += all: $(TARGETS) .PHONY: clean clean: $(RM) *~ *.o $(TARGETS)
かなりすっきりしました。本当はもっとストイックに切り詰めたほうがいいのかもしれませんが、個人的にはcleanが欲しいのでこうしてあります。今後も改善していきたいです。
謝辞
個人的には、まさに発想の転換というか、目からうろこでした。makingさん、pyopyopyoさんありがとうございます!