お気に入りMakefile
普段使っているMakefileは以下の通り.
CC = g++ CFLAGS = -std=c++11 LDFLAGS = LIBS = INCLUDE = -include ./include SRC_DIR = ./src OBJ_DIR = ./obj BIN_DIR = ./bin SRC_SUF = .cxx OBJ_SUF = .o DIP_SUF = .d BIN_SUF = TARGET = run SOURCES = $(shell ls $(SRC_DIR)/*$(SRC_SUF)) OBJS = $(subst $(SRC_DIR),$(OBJ_DIR), $(SOURCES:$(SRC_SUF)=$(OBJ_SUF))) TARGETBIN = $(addprefix $(BIN_DIR)/, $(TARGET)) DEPENDS = $(OBJS:$(OBJ_SUF)=$(DIP_SUF)) all: $(TARGETBIN) $(TARGETBIN): $(OBJS) $(LIBS) @if [ ! -d $(BIN_DIR) ]; \ then echo "mkdir -p $(BIN_DIR)"; mkdir -p $(BIN_DIR); \ fi $(CC) $(CFLAGS) -o $@ $(OBJS) $(LDFLAGS) $(OBJ_DIR)/%.o: $(SRC_DIR)/%$(SRC_SUF) @if [ ! -d $(OBJ_DIR) ]; \ then echo "mkdir -p $(OBJ_DIR)"; mkdir -p $(OBJ_DIR); \ fi $(CC) $(CFLAGS) $(INCLUDE) $(LDFLAGS) -o $@ -c $< clean: $(RM) -rf $(OBJ_DIR) $(BIN_DIR) $(DEPENDS) -include $(DEPENDS)
説明
Makefileの基本的な構文は
<task> : (必要なファイル) シェルで実行したいコマンド
の形を取っている.taskを実行するのに必要なファイルがあった場合,それを作成するためのタスクが先に呼ばれて…となる.たとえば
aho : echo "aho"
というMakefileを作って
$ make aho aho
と返ってくる.この場合は必要なファイルがないのでahoのコマンドだけが実行される.先頭に@をつけるとコマンドの結果を標準出力に出さない様にできる.if文みたいに改行するようなコマンドだと,\をつける必要がある.コマンドのところで改行すると,別々のコマンドと解釈される.
変数の設定もできて上の例だとCC=g++みたいなところがそう.
変数に値を追加して行くこともできて
hoge = fuga1 hoge += fuga2 hoge += fuga3
などもできる.変数のアクセスは$(hoge)とすればよい.
SOURCES = $(shell ls $(SRC_DIR)/*$(SRC_SUF))
$(shell ...)とすると,シェルの結果を変数に代入できる.上の場合だと,
ls ./src/*.cxx
の結果がSOURCESに入る.ちなみに上のMakefileではSOURCES変数は書いたけど使っていない.
OBJS = $(subst $(SRC_DIR),$(OBJ_DIR), $(SOURCES:$(SRC_SUF)=$(OBJ_SUF))) TARGETBIN = $(addprefix $(BIN_DIR)/, $(TARGET))
substとかaddprefixはMakefileで使える関数.他にもたくさんある.
subst $(from), $(to), $(text)
では$(text)の$(from)を$(to)に置換.上記例だと$(text)は
$(SOURCES:$(SRC_SUF)=$(OBJ_SUF))
になっている.
$(hoge:$(old)=$(new))
で,$(hoge)の$(old)を$(new)に置き換えることになる.
addprefix $(add), $(to)
で$(to)に$(add)を追加できる.