$Id: Readme-mffw.html,v 1.8 2002/11/07 06:54:30 oka Exp $ Date: 2001/01/14 author: OKA Toshiyuki Copyright (c) 2001-2002 by LangEdge Inc. #----------------------------------------------------------------------- # 使用・複製・修正・配布に関する許諾条件: # 本ファイルは、以下の5条件が全て遵守される場合に限り、公序良俗に反しな # い範囲で、商用・非商用を問わず、いかなる個人または組織に対しても対価を # 支払うことなく、誰でも自由に、使用・複製・修正・配布の全部または一部の # 行為を行うことができる。 # # (1) この「使用・複製・修正・配布に関する許諾条件」にある文言を一切修正 # しないこと。 # # (2) ファイルの先頭部に記述してある author行および Copyright行または、 # そのいずれかを削除したり修正したりしないこと。ただし、author行また # は Copyright行で記述されている当の個人または組織 (以後、「著作者」 # と呼ぶ) は、自身に関する記述に限り、削除したり修正したりすることが # できる。 # # (3) ファイルに何らかの修正を加えた場合には、修正した個人または組織に関 # する author行と Copyright 行を追加することができる。その場合、追加 # された記述に対しても (2)項の規定が適用される。 # # (4) 本ファイルを使用、複製、修正または配布した結果として、いかなる種類 # の損失、損害または不利益が発生しても、「著作者」がその責を一切負わ # ないことに同意し、かつ「著作者」にその責を一切負わせないこと。 # # (5) 本ファイルをコンパイラに適用して得られたバイナリオブジェクトは、そ # のコンパイルを実行した個人または組織の所有物であり、「著作者」との # 間には、一切の権利・義務関係が存在しないことに同意する。 #-----------------------------------------------------------------------
C/C++ を使用するプロジェクト用に、汎用で使える Makefile のフレームワーク (以下、mffw と呼ぶ) を用意した。各プロジェクトは、このフレームワークを使 用することで、自前の Makefile を用意しなくても、一通りの作業を行うことが できる。
とりあえず使ってみるためには、次のようにする:
gmake にする。
Linux や *BSD なら標準で装備されていると思う。
Windows の場合は cygwin を導入するとよい。
% cp Makefile Makefile.fw {ProjectDir}/
% cd {ProjectDir}
% vi mffw.conf
'debug' というディレクトリが作られ、その中に、 コンパイルされたオブジェクトやコマンドが格納される。% gmake
samle というディレクトリに単純なプロジェクトを用意しておいたので、
ここに Makefile と Makefile.fw をコピーして gmake を実行してみるとよいだろう。
(本稿末尾の「典型的なプロジェクト構成」を参照)
% cp Makefile Makefile.fw sample/ % cd sample % gmake % main/debug/main
Makefile.fw は、最初に作業ディレクトリにある mffw.conf というファイルを インクルードする。mffw.conf にソースファイル(群)の名前とターゲットの名前 を書いておく。
ターゲット指定として、少なくとも次のうちの1つを定義しなければならない。
CMDTARGET |
作成するコマンド名 |
LIBTARGET |
作成するライブラリ名 |
設定ファイルでターゲットだけが指定されている場合、mffw は作業ディレクトリ に格納されているソースファイルを勝手にコンパイル & リンクする。
[例]この例では foo という名前の実行ファイルを作成することを指示している。ソー スファイルの指定がないので、作業ディレクトリに格納されているソースファイ ルをすべてコンパイル & リンクして foo という名前の実行ファイルを作成する。 (sample/foo/mffw.conf も参照のこと)CMDTARGET := foo
ターゲットを構成するソースファイルを明示的に指定するには、次の変数を設定 する。
CMDSRCS |
CMDTARGET に直接リンクされるオブジェクトのソースファイル |
LIBSRCS |
LIBTARGET の構成要素になるオブジェクトのソースファイル |
YACCSRCS |
yacc で処理されるソースファイル |
LEXSRCS |
lex で処理されるソースファイル |
これらの変数には、スペースで区切って複数のファイル名を記述することができ る。
[例]この例では foo.cpp および bar.c をコンパイルして foo.a というライブラリを 作成することを指示している。LIBTARGET := foo.a LIBSRCS := foo.cpp bar.c
もし上記ソースファイルが一つも指定されていなかった場合は、
CMDTARGET が定義されていれば、作業ディレクトリに含まれる
*.cpp, *.cc, *.c ファイルが CMDSRCS に設定される。
LIBTARGET が定義されていれば、作業ディレクトリに含まれる
*.cpp, *.cc, *.c ファイルが LIBSRCS に設定される。
したがって、設定ファイルに CMDTARGET または LIBTARGET
を記述するだけで、
作業ディレクトリに格納されているソースファイルからターゲットを作成することが可能である。
さらに、
CMDTARGET に 'build_each' が定義されている:CMDSRCS の個々のソースに対してコンパイル & リンクが行われる。
実行ファイル名はソースファイル名から拡張子を取り除いたものになるCMDTARGET に 'not_bind' が定義されている:CMDSRCS の個々のソースに対してコンパイルのみが行われ、
リンクは行われない。CMDTARGET に上記以外のものが定義されている:CMDSRCS, YACCSRCS, LEXSRCS
で指定されたソースファイルをコンパイルして生成されるオブジェクトファイルは、
CMDTARGET をビルドするために直接リンクされる。LIBTARGET が定義されている:LIBSRCS, YACCSRCS, LEXSRCS
で指定されたソースファイルをコンパイルして生成されるオブジェクトファイルは、
LIBTARGET の構成要素となる。となる。
他にも以下のような変数を設定できる。
PROJECT |
プロジェクト名を指定する。make 開始時のバナー表示で使用する。 (省略時: カレントの作業ディレクトリ名) |
ROOTDIR |
種々のディレクトリ指定の起点となるディレクトリ。フルパスで指定する。 (省略時: プロジェクトのトップディレクトリ) |
SUBDIRS |
当該作業ディレクトリのビルド前にビルド処理を実行しておきたいサブディレクトリを指定。
ディレクトリ名をスペースで区切って複数指定することができる。 例: SUBDIRS := foo bar
|
POSTDIRS |
当該作業ディレクトリのビルド後にビルド処理を実行させたいサブディレクトリを指定。
ディレクトリ名をスペースで区切って複数指定することができる。 例: POSTDIRS := foo bar
|
COMMON_INCDIRS |
プロジェクト全体で共通に参照されるヘッダーファイルのサーチパスを指定。
ディレクトリ名をスペースで区切って並べる。この指定はサブディレクトリにも伝播する。 例: COMMON_INCDIRS := $(ROOTDIR)/include /proj/include
|
INCDIRS |
個々の作業ディレクトリごとに指定するヘッダーファイルのサーチパスを指定。
COMMON_INCDIRS の指定とマージされる。
ディレクトリ名をスペースで区切って並べる。サブディレクトリには伝播しない。(省略時: .) |
CMDTARGETDIR |
コマンドターゲットを作成する場所。この指定は、サブディレクトリにも伝播する。 例: CMDTARGETDIR := $(ROOTDIR)/bin/$(BUILDCONFIG)(省略時: ./$(BUILDCONFIG)) |
CMDDIR |
コマンドターゲットを作成する場所。
この指定は上位ディレクトリにおける CMDTARGETDIR の指定よりも優先されるが、
当該作業ディレクトリでのみ有効となる。 |
LIBTARGETDIR |
ライブラリターゲットを作成する場所。この指定は、サブディレクトリにも伝播する。 例: LIBTARGETDIR := $(ROOTDIR)/libs/$(BUILDCONFIG)(省略時: ./$(BUILDCONFIG)) |
LIBDIR |
ライブラリターゲットを作成する場所。
この指定は上位ディレクトリにおける LIBTARGETDIR の指定よりも優先されるが、
当該作業ディレクトリでのみ有効となる。 |
OBJTARGETDIR |
オブジェクトファイルを作成する場所。この指定は、サブディレクトリにも伝播する。 例: LIBTARGETDIR := $(ROOTDIR)/objs/$(BUILDCONFIG)(省略時: ./$(BUILDCONFIG)) |
OBJDIR |
オブジェクトファイルを作成する場所。
この指定は上位ディレクトリにおける OBJTARGETDIR の指定よりも優先されるが、
当該作業ディレクトリでのみ有効となる。 |
COMPILER |
使用する C++ コンパイラのコマンド名を指定する。 (省略時: g++) |
CCOMPILER |
使用する C コンパイラのコマンド名を指定する。 (省略時: gcc) |
RELEASE_FLAGS |
リリース用のコンパイル/リンクスイッチ。サブディレクトリにも伝播する。 (省略時: -O -DNDEBUG) |
DEBUG_FLAGS |
デバッグ用のコンパイル/リンクスイッチ。サブディレクトリにも伝播する。 (省略時: -g -D_DEBUG -DDEBUG) |
WARNING |
警告レベルの制御スイッチ。サブディレクトリにも伝播する。 (省略時: -Wall) |
CPPDEFINES |
プロジェクトで共通に指定するプリプロセッサ用定義。 |
LINKER |
使用するリンカのコマンド名およびオプションを指定する。 |
DEBUG_LDFLAGS |
デバッグ用のリンクスイッチ。サブディレクトリにも伝播する。 (省略時: -g) |
RELEASE_LDFLAGS |
リリース用のリンクスイッチ。サブディレクトリにも伝播する。 (省略時: -static) |
NoStrip |
定義すると、リリース用コマンドをビルドした後に、strip を行わない。 デフォルトでは リリース用コマンドをビルドした後は、strip が実行される。 |
ARCHIVER |
使用するアーカイバのコマンド名およびオプションを指定する。 (省略時: ar rs) |
CMDOBJS |
当該作業ディレクトリ内では管理されていないが、
CMDTARGET を作成する際には一緒にリンクされるオブジェクト。
スペースで区切ることにより複数指定可。 |
LIBS |
当該作業ディレクトリ内では管理されていないが、
CMDTARGET を作成する際には一緒にリンクされるライブラリ。
スペースで区切ることにより複数指定可。 |
LIBOBJS |
当該作業ディレクトリ内では管理されていないが、
LIBTARGET を作成する際には一緒にアーカイブに取り込まれるオブジェクト。
スペースで区切ることにより複数指定可。 |
YaccLexClean |
定義すると、yacc/lex で生成される C/C++ ソースも clean の対象になる。 |
これらの変数は mffw.conf で記述する以外に、環境変数として指定してもよい。
上記の変数の記述の際に、以下の Makefile.fw 内部変数を使用できる:
BUILDCONFIG |
構成種別情報。 release または debug に設定される |
mffw.conf の例
添付の Makefile は Makefile.fw のラッパーである。 Makefile.fw と このラッパー Makefile をプロジェクトのトップディレクトリに コピーし、各作業ディレクトリに mffw.conf を配置すれば、一応のビルドシス テムが出来上がる。
ラッパー Makefile には、ターゲットとして
debug /
release /
clean /
depend
が記述されている。それぞれ、
make debug ⇒ gmake -f Makefile.fw debug=1 make release ⇒ gmake -f Makefile.fw release=1 make clean ⇒ gmake -f Makefile.fw clean make depend ⇒ gmake -f Makefile.fw depend
を実行する。
make debug
デバッグ用ビルドを実行する。
構成情報として、BUILDCONFIG 変数が 'debug' に設定される。
オブジェクトやライブラリ、コマンドは、デフォルトでは ./debug/ ディレクトリに作成されるが、
OBJTARGETDIR, LIBTARGETDIR, CMDTARGETDIR
を設定することにより、格納場所を指定することができる。
make release
リリース用ビルドを実行する。
構成情報として、BUILDCONFIG 変数が 'release' に設定される。
オブジェクトやライブラリ、コマンドは、デフォルトでは ./release/ ディレクトリに作成されるが、
OBJTARGETDIR, LIBTARGETDIR, CMDTARGETDIR
を設定することにより、格納場所を指定することができる。
make cleanオブジェクトファイル、ライブラリファイル、コマンドファイルおよび依存関係ファイル (depend.mf) を消去する。一からフルビルドを実行したいときに用いる。
make depend
make の ターゲットとして depend を指定すると、
ソースファイルとヘッダーファイルの依存関係を記述したファイル (depend.mf) を生成する。
ソースファイルやヘッダーファイルをプロジェクトに追加したときは、
必ず make depend を実行すべきである。
mffw.conf に、SUBDIRS または POSTDIRS を記述すると、
それらで指定された各サブディレクトリ dir に対して、
gmake -f Makefile.fw -C $(dir) $(BUILDCONFIG)=1 target
を実行する。
SUBDIRS で指定されたディレクトリはカレントの作業ディレクトリより前に処理され、
POSTDIRS で指定されたディレクトリはカレントの作業ディレクトリより後に処理される。
標準的なビルドプロセスから外れた処理を実行したい場合は、customrules.mf というファイルにルールを記述する。
customrules.mf は、Makefile と Makefile.fw の両方に、それぞれの末尾でイン
クルードされる。Makefile.fw では、'MakefileFramework' が定義されているの
で、ifdef MakefileFramework を使用して、それぞれのルールを切り替えるとよ
い。
強制的に実行させたいルールがある場合は、
そのルールのトリガーとなるターゲット(複数可)を
CUSTOMTARGETS という変数に記述する。
メインのビルドプロセスに先立ち、
CUSTOMTARGETS に記述されたターゲットの処理が実行される。
例: EUCのソースを SJISのソースに変換するCUSTOMTARGETS := foo_sjis.cpp foo_sjis.cpp: foo_euc.cpp nkf -s $^ > $@
例2: テストを実行するターゲットを付加するtest: ifdef MakefileFramework $(BUILDCONFIG)/testprog # テストプログラムの実行 else gmake -f Makefile.fw test # Makefil.fw の test を呼び出す endif
添付の unitmake というシェルスクリプトを使うと、複数階層のディレクトリ ツリーから構成されているプロジェクトにおいて、あるサブディレクトリツリー の下だけをビルドすることができる。当該サブディレクトリに移動し、 unitmake を実行すればよい。
% cd <サブディレクトリ> % unitmake
unitmake は、Makefile.fw が見つかるまで、コマンドを実行したディレクトリ から上にたどってゆき、Makefile.fw が見つかったところで、今度は逆順にデ ィレクトリツリーを降りてくる。その際、通過するディレクトリにある mffw.conf の設定が読み込まれる。
sample/
└┬─ Makefile (添付 Makefile をコピーする)
├─ Makefile.fw (添付 Makefile.fw をコピーする)
│
├─ mffw.conf
│ SUBDIRS = foo yacc main
│ ROOTDIR := $(shell pwd)
│ OBJTARGETDIR = $(ROOTDIR)/objects/$(BUILDCONFIG)
│ LIBTARGETDIR = $(ROOTDIR)/libs/$(BUILDCONFIG)
│
├─ foo/
│ └┬─ mffw.conf
│ │ LIBTARGET = foo.a
│ │
│ ├─ foo1.cpp
│ └─ foo2.cpp
│
├─ yacc/
│ └┬─ mffw.conf
│ │ YaccLexClean = 1
│ │ YACCSRCS = yacc.y
│ │
│ ├─ yacc.y
│ ├─ yacc.tab.c (yacc によって生成される)
│ ├─ yacc.tab.h (yacc によって生成される)
│ │
│ ├─ release/ (自動的に作成される)
│ │ └── yacc.tab.o
│ │
│ └─ debug/ (自動的に作成される)
│ └── yacc.tab.o
│
├─ main/
│ └┬─ mffw.conf
│ │ CMDTARGET = main
│ │ CMDSRCS = main.cpp
│ │ CMDOBJS = $(OBJTARGETDIR)/yacc.tab.o
│ │ LIBS = $(LIBTARGETDIR)/foo.a
│ │
│ ├─ main.cpp
│ │
│ ├─ debug/ (自動的に作成される)
│ │ └─ main
│ │
│ └─ release/ (自動的に作成される)
│ └─ main
│
├─ objects/ (自動的に作成される)
│ └┬─ debug/ (自動的に作成される)
│ │ └┬─ foo1.o
│ │ ├─ foo2.o
│ │ ├─ yacc.tab.o
│ │ └─ main.o
│ │
│ └─ release/ (自動的に作成される)
│ └┬─ foo1.o
│ ├─ foo2.o
│ ├─ yacc.tab.o
│ └─ main.o
│
└─ libs/ (自動的に作成される)
└┬─ debug/ (自動的に作成される)
│ └─ foo.a
│
└─ release/ (自動的に作成される)
└─ foo.a