Last active
May 13, 2017 11:32
-
-
Save motchy869/978133e7f71d060e680057f026b63d76 to your computer and use it in GitHub Desktop.
Windows用Makefile。ソースファイル自動検索+プリコンパイル済みヘッダ対応
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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