マイmakefile

 ちょっとNyRさんの所でmakeの話(id:NyR:20050512)になり、私のmakefileを見てみたいということ。
 正直、卑怯臭く図太く色々とあれなmakefile……


#
# MakeFile for D
#
# Author      : Dear Periwinkle
# E-Mail      : nayuri@kuonn.mydns.jp
# SiteAddress : http://kuonn.mydns.jp/
#
#  Target is all, compile, clean.
#

# Configuration

# ProjectName
PROJECT = ○○

# OperatingSystem
#  Win32, Linux
OS = Win32

# Compose
#  debug, release
COMPOSE = debug

# SourceFile Directory
SRCDIR = src

# ImportFile Directory
IMPDIR = import

# LibraryFile Directory
#  debug directory and release directory in this directory
LIBDIR = lib

# ResourceFile Directory
RESDIR = resource

# D Compiler
DMD = dmd

# End Configuration
# After Don't Touch

ifeq ($(OS), Win32)
OBJEXT = .obj
LIBEXT = .lib
endif
ifeq ($(OS), Linux)
OBJEXT = .o
LIBEXT = .a
endif

ifeq ($(COMPOSE), debug)
DFLAG = -g -debug
endif
ifeq ($(COMPOSE), release)
DFLAG = -O -release -inline
endif

SRC = ${wildcard $(SRCDIR)/*.d $(SRCDIR)/*/*.d $(SRCDIR)/*/*/*.d $(SRCDIR)/*/*/*/*.d $(SRCDIR)/*/*/*/*/*.d}
IMP = ${wildcard $(IMPDIR)/*.d $(IMPDIR)/*/*.d $(IMPDIR)/*/*/*.d $(IMPDIR)/*/*/*/*.d $(IMPDIR)/*/*/*/*/*.d}
LIB = ${wildcard $(LIBDIR)/$(COMPOSE)/*$(LIBEXT)}
OBJ = ${patsubst %.d,%$(OBJEXT),$(SRC) $(IMP)}
RES = ${wildcard $(RESDIR)/*}

all: $(OBJ)
	$(DMD) $(OBJ) $(LIB) $(RES) $(DFLAG) -of$(PROJECT)
ifeq ($(COMPOSE), debug)
	$(PROJECT)
endif
ifeq ($(COMPOSE), release)
	$(MAKE) clean
endif

%$(OBJEXT):%.d
	$(DMD) -c $< -I$(SRCDIR) -I$(IMPDIR) $(DFLAG) -of$@

compile: $(OBJ)

clean:
ifeq ($(OS), Win32)
	del $(subst /,\\,$(OBJ)) $(PROJECT).map
endif
ifeq ($(OS), Linux)
	rm -f $(OBJ)
endif

これ一つでWin32もLinuxもという図太さ……CGI作ってる時にわざわざ面倒だったので……。
使い方は、読めば分かる程度ですが一応説明。(make分かってる人は読む必要ないと思う、読んだ方が私の言葉より分かり易いかと。ifeqだらけでソース汚いですけどね!)
まずファイル構造

  • make.exe(eclipseならばルートなりワークスペースなりにでも置いて、作業フォルダをここにすれば、ここに置く必要も無いです)
  • makefile(上記の奴が書かれた奴です)
  • src[Directory]
    • Dソース群
  • import[Directory](無くても可、make時に空欄になるだけなのでエラーは出ません)
    • なんかSDLやらyaneSDK4Dとか、何かimportするなら、src内じゃなくてもここでも可
  • lib[Directory](無くても可、make時に空欄になるだけなのでエラーは出ません)
    • debug[Directory]
      • debug時にLinkするライブラリー
    • release[Directory]
      • release時にLinkするライブラリー
  • resource[Directory](無くても可、make時に空欄になるだけなのでエラーは出ません)
    • Linkするリソース

 こんな感じ、ちなみに68行目で実行ファイルをRunさせています。これはeclipseだと外部実行なんぞ登録するのも面倒だし、かといってナビゲーターから実行するとログが見えない為。実行したら困る場合はコメントアウトでも。
 上の方の設定は……見たら分かると思います。ProjectNameはまんま吐き出すexeの名前ですし、OSやComposeは選ぶだけです。そこからはDirectoryの名称設定なので上のリストの通りの構造にするのなら、そのままで問題なし。
 $DMDはPATH環境変数を通せばdmdコマンドでコンパイラが動きますが、して無い場合は C:\dmd\bin\dmd とかに設定でもしてください。
 ターゲットは「all」、「compile」、「clean」です。でも、eclipseだと多分「all」くらいしか実行すること無いと思う。わざわざプロジェクトのプロパティ開くのも面倒だし。一応ってだけだね「compile」と「clean」を用意したのは……。
 参考になるかどうかも分からないけど、こんな感じです、私のmakefile。ちなみにオブジェクトファイルはソースと同じ場所に出来るので結構邪魔になります。結局それは解決できず……結構勉強したのですが。毎回フルリビルドでも良いというのなら別フォルダに吐き出すのも可能ですが。
 そっちの方は……教えて欲しければ教えます。私ので良いのなら。まぁ、Dはコンパイル、リンク早いしねぇ、ある程度までのプロジェクトなら、そっちでも十分だったりします。