このページの内容

multiconf.make

multiconf.makeは、同じターゲットをさまざまなフラグの組み合わせでビルドするための、単体で使えるMakefileインクルードです。たとえば、デバッグとリリース、ASanとUBSan、GCCとClangを切り替えられます。 フラグの組み合わせごとにオブジェクトファイルを専用のキャッシュディレクトリーへ生成するため、ある設定でコンパイルしたオブジェクトを別の設定で再利用することはありません。 以前の設定のオブジェクトファイルは保持されるので、その設定へ戻すときは、実際に変更されたオブジェクトだけをコンパイルすれば済みます。


利点の一覧

利点multiconf.makeの動作
設定の分離フラグの組み合わせごとに1つのディレクトリーを用意し、cachedObjs/<hash>/にオブジェクトを保存します。
高速な切り替え以前の設定はすぐに再利用でき、リンクだけを行い、再コンパイルはしません。
ヘッダーへの依存ヘッダーを編集すると、必要なものだけを再ビルドします。
1行でターゲットを定義マクロ(c_program、cxx_programなど)が、規則の定型記述を隠します。
並列実行に対応make -jで安全に使え、共有するソースを重複してコンパイルしません。
出力の詳しさを制御デフォルトではオブジェクトだけを一覧表示し、V=1ではコマンド全体を表示します。
cleanも用意make cleanはすべてのオブジェクト、バイナリー、リンクを削除します。

使い始める

1 · ソースを列挙する

C_SRCDIRS   := src src/cdeps    # all .c are in these directories
CXX_SRCDIRS := src src/cxxdeps  # all .cpp are in these directories

2 · 追加してインクルードする

# root/Makefile
include multiconf.make

3 · ターゲットを宣言する

app:
$(eval $(call c_program,app,app.o cdeps/obj.o))

test:
$(eval $(call cxx_program,test, test.o cxxdeps/objcxx.o))

lib.a:
$(eval $(call static_library,lib.a, lib.o cdeps/obj.o))

lib.so:
$(eval $(call c_dynamic_library,lib.so, lib.o cdeps/obj.o))

4 · 好きな設定でビルドする

# Release with GCC
make CFLAGS="-O3"

# Debug with Clang + AddressSanitizer (new cache dir)
make CC=clang CFLAGS="-g -O0 -fsanitize=address"

# Switch back to GCC release (objects still valid, relink only)
make CFLAGS="-O3"

各コマンドのオブジェクトは異なるサブフォルダーに置かれ、互いに重複しません。