Skip to content

Instantly share code, notes, and snippets.

@motchy869
Last active May 13, 2017 11:32
Show Gist options
  • Save motchy869/978133e7f71d060e680057f026b63d76 to your computer and use it in GitHub Desktop.
Save motchy869/978133e7f71d060e680057f026b63d76 to your computer and use it in GitHub Desktop.
Windows用Makefile。ソースファイル自動検索+プリコンパイル済みヘッダ対応
#makefile for Windows
#プログラム名
PROGNAME := main
#ビルドタイプ
BUILD_TYPE := debug
#プログラミング言語(C, C++)
LANG := C++
#コンパイラ, ソースファイル拡張子
ifeq ($(LANG), C)
CMP := gcc
SRCEXT := c
else ifeq ($(LANG), C++)
CMP := g++
SRCEXT := cpp
endif
#ソースファイル検索
#(dir の出力は改行区切りだが、make内で変数に代入する際に自動的に半角スペース区切りになるらしい)
SRCS := $(subst $(CURDIR)/,,$(subst \,/,$(shell dir *.$(SRCEXT) /b /a-d /s)))
#プリコンパイル対象ヘッダ
PCH_H := $(subst $(CURDIR)/,,$(subst \,/,$(shell dir pch.h /b /a-d /s)))
#コンパイルオプション, プリコンパイル済みヘッダ
CMPFLAGS := -Wall
ifeq ($(BUILD_TYPE), release)
CMPFLAGS += -DNDEBUG -O3
PCH_GCH := $(PCH_H).gch/release.h.gch
else ifeq ($(BUILD_TYPE), debug)
CMPFLAGS += -O0 -g
PCH_GCH := $(PCH_H).gch/debug.h.gch
endif
#実行時引数
ARG :=
#出力先ディレクトリ
OUTDIR := ../build/$(BUILD_TYPE)
#実行ファイルパス
EXEPATH := $(OUTDIR)/$(PROGNAME)
#オブジェクトファイル
OBJS := $(SRCS:%.$(SRCEXT)=$(OUTDIR)/%.o)
#ヘッダ依存関係情報ファイル
DEPS := $(SRCS:%.$(SRCEXT)=$(OUTDIR)/%.d)
.PHONY: default
default: $(EXEPATH)
#プログラム実行
.PHONY: run
run: $(EXEPATH)
$(EXEPATH) $(ARG)
#依存関係情報ファイルのインクルード
-include $(DEPS)
#実行ファイル生成
$(EXEPATH): $(PCH_GCH) $(OBJS)
$(CMP) $(LDFLAGS) -o $@ $(OBJS)
#プリコンパイル済みヘッダ生成
$(PCH_GCH): $(PCH_H)
@if not exist $(subst /,\,$(dir $@)) mkdir $(subst /,\,$(dir $@))
$(CMP) -o $@ $(CMPFLAGS) $<
#オブジェクトファイルとヘッダ依存関係情報ファイルを生成
#本当は -MMD で依存関係情報ファイル生成と同時にコンパイルしたいのだが、 -MMD だと何故かプリコンパイル済みヘッダが記載されないので、仕方なく一旦 -MM で依存関係情報ファイルだけ作る。
#厄介なことに -MM だと .o ファイルがフルパスにならないので、ディレクトリ情報だけをシェルで先に出力し、g++ の結果を追記する。
#ディレクトリ情報の次に改行を入れないために set コマンドに細工が要る。set が何故か常にエラーを返すので ||rem hoge で結果を強制的に true にしてエラーを黙殺する。
$(OUTDIR)/%.o: %.$(SRCEXT)
@if not exist $(subst /,\,$(dir $@)) mkdir $(subst /,\,$(dir $@))
@set /p=$(dir $@)<nul>$(subst /,\,$(@:%.o=%.d))|| rem hoge
$(CMP) $(CMPFLAGS) -MM -MP -c $< >> $(subst /,\,$(@:%.o=%.d))
$(CMP) $(CMPFLAGS) -o $@ -c $<
#クリーニング
#ファイルがない場合に del が煩いので >nul 2>&1 で黙らせる。
.PHONY: clean
clean:
@del /f /q $(subst /,\,$(EXEPATH)).exe $(subst /,\,$(OBJS)) $(subst /,\,$(DEPS)) $(subst /,\,$(PCH_GCH)) >nul 2>&1 || rem hoge
#削除
.PHONY: remove
remove:
@if exist $(subst /,\,$(OUTDIR)) rd /s /q $(subst /,\,$(OUTDIR))
@if exist $(subst /,\,$(PCH_H).gch) rd /s /q $(subst /,\,$(PCH_H).gch)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment