search
LoginSignup
7

More than 3 years have passed since last update.

posted at

updated at

汎用のMakefile ー これひとつで手間いらず ー

Makefileを書くのはめんどいがIDEをいちいち起動するのもタルい…とゆう問題意識を俺はこの20年余りずっと持ち続けてきた。実に四半世紀近くにも渡る苦悩の日々であったのだが、先日インターネットをだらだら見ていたところ、g++/clang++のオプション指定で依存関係ファイルを自動生成しMakefileを汎用化している人を発見したのだった。すげー。

【Makefile】依存関係を自動生成する試み2014
https://td2sk.hatenablog.com/entry/20141213/1418429143

残念ながら俺のパチョコン(OS X 10.13.6)ではこのMakefileは正常に動作しなかったが、暇にまかせ自分で試行錯誤してみた結果まあまあ望み通りのものができたので以下にご紹介。

CXX = g++

FLGS = -std=c++14
CXXFLAGS = $(FLGS) -g -Wall -W

LDFLAGS =
LDLIBS =

OUT_DIR = out
OUT_FLGS = $(FLGS) -O3 -DNDEBUG
OUT_LDFLGS = $(LDFLAGS)
OUT_LDLIBS = $(LDLIBS)

################################################################

SRCS = $(wildcard *.cpp)
DEPS = $(SRCS:.cpp=.d)
EXEC = $(shell basename `pwd`)
CXXFLAGS += -MMD -MP
OBJS = $(SRCS:.cpp=.o)
OUT_SRCS = $(addprefix $(OUT_DIR)/, $(wildcard *.cpp))
OUT_OBJS = $(addprefix $(OUT_DIR)/, $(SRCS:.cpp=.o))

.PHONY: debug
debug: $(EXEC)

$(EXEC): $(OBJS)
    $(CXX) -o $(EXEC) $(LDFLAGS) $(LDLIBS) $(OBJS)

-include $(DEPS)

.PHONY: clean
clean:
    rm -f $(EXEC) $(OBJS) $(DEPS)
    rm -f $(OUT_DIR)/$(EXEC) $(OUT_OBJS)

.PHONY: release
release: $(OUT_DIR)/$(EXEC)

$(OUT_DIR)/$(EXEC): $(OUT_DIR) $(OUT_OBJS)
    $(CXX) -o $(OUT_DIR)/$(EXEC) $(OUT_LDFLGS) $(OUT_LDLIBS) $(OUT_OBJS)

$(OUT_DIR):
    mkdir -p $(OUT_DIR)

$(OUT_DIR)/%.o: %.cpp %.o
    $(CXX) $(OUT_FLGS) -c -o $@ $<

基本的な使い方は上記のコードをMakefileという名前のファイルにしてC++のソース群と同じフォルダに置く。コーディングが済んだらコマンドラインからmake(またはmake debug)と入力!するとフォルダと同じ名前の実行ファイルができあがる。楽チンw

最適化した実行ファイルを得たいときはmake releaseと入力するとoutというフォルダに出力される。またmake cleanと入力すると中間ファイルおよび実行ファイルを消去する。

注意点としてmakeはタブ文字以外のインデントを受け付けないので、上記のコードをテキストエディタに貼り付けた後にスペース文字のインデントをタブ文字に変換する必要がある。

欠点はソースファイル・中間ファイル・依存関係ファイル・実行ファイルがみんな同じフォルダにゴチャッと混ざること。これは上述のコンパイラオプションとの兼ね合いでこうなったのだが、改善の余地があるかもしれない。

カスタマイズは基本シャープ文字の横線より上の部分だけを編集する。参考までに、俺の環境でPython3.7を組み込みたい時のカスタマイズ例は以下のようになる。

CXX = g++

FLGS = -std=c++14 -I/Library/Frameworks/Python.framework/Versions/3.7/include/python3.7m

CXXFLAGS = $(FLGS) -g -O0 -Wall -W

LDFLAGS = -L/Library/Frameworks/Python.framework/Versions/3.7/lib
LDLIBS = -lpython3.7m

OUT_DIR = out
OUT_FLGS = $(FLGS) -O3 -DNDEBUG
OUT_LDFLGS = $(LDFLAGS)
OUT_LDLIBS = $(LDLIBS)

いじょう

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
What you can do with signing up
7