Libera me, Domine, de morte aeterna in die illa tremendae

今のC++おしごとの自分の担当範囲ではビルドシステムにwafを使っている.

使用感としては,ぶっちゃけGNU Makeに比べて本質では大差ないが,微妙に便利と呼べる面もあるのでプラマイ総計ではプラスだろうと判断して使っている.特徴*1はデフォでC++ヘッダの依存性を見てくれるとか,デフォでCPUコア数の並列ビルドしてくれるとか,デフォでコンソール出力に色が付くとかね... しかし,なかなか十分とは言い切れない.C++おしごとという苦行が際立って楽になる感じはしない.どうか私をお救いください.
私には夢がある.いつの日かC++対応のビルドシステムが,#include のスキャンによる .cpp → .o 過程の依存性の自動解析のみならず,作られた .o たちのリンク過程の依存性も自動解析してくれる日が来るという夢が... (別に自分で書こうという予定は今のところ無い.)
これが問題になるのはユニットテストだ.C++でモジュールの最小単位はオブジェクトファイル .o であろう.ユニットテストも個々のオブジェクトファイルを対象にまとめるのが自然だと思う.(ここではオブジェクトファイル1個ごとにどれだけのクラスを含むようにモジュール化すべきかについては触れない.)これがめんどい... fooTest.exe には foo.o だけでなく,それが依存する util.o と global.o と librt.so をリンクしないとエラーとか,微妙にジャブのように生産性を削ぐ.まぁでも use 引数を再帰的に辿るPythonコード追加すれば半自動で実現できるかなー.ここで「辿る」ためには,Wafのクラス設計を勉強してかないといけなさそうなんだよな... 以下に nm(1) 使ってなんかやる拡張をやったというSamba4の中の人の利用実績を貼っておく:

なお日本人でwafに関心を持った人なら,ちょっと調べると id:tanakh さんの紹介記事に行き着くだろう.

でも紹介記事が書かれた当時からバージョンがかなり変わっているので紹介された通りには全然動かない.Waf bookをきちんと読むのは結局避けられない.Waf bookと言えば,「ふつうのUnixプログラマ」がGNU Makeでふつうに実現できる/してきたことがwafだとWaf bookをやはりきちんと読まないとできないとか,そういうのが「プラマイ」で言うマイナス部分である...
ちなみにout-of-tree buildをサポートする新し目のビルドシステムなんだからDebugビルドとReleaseビルドを別々に出すことくらいできるよね? と思って調べると,こんな感じでPython書くことになるようだ.これだとReleaseビルド(デフォ)の出力ディレクトリが release/ でなく build/ になるけど,まぁ気になるなら変えればいいかな.

def configure(cnf):
    cnf.load('compiler_cxx waf_unit_test')

    cnf.env.CXXFLAGS += [ '-Wall', '-Wextra', '-Wno-missing-field-initializers',
            '-Wno-multichar', '-std=c++0x', '-g3' ]

    outdir = cnf.bldnode.name
    if 'build' == outdir:
        cnf.env.CXXFLAGS += [ '-O3' ]
    elif 'debug' == outdir:
        cnf.env.CXXFLAGS += [ '-O0' ]
    else:
        sys.stderr.write("Unsupported OUT (%s) was specified;  will proceed anyways...\n" % outdir)

*1:「利点」と言い切ることはあえてしない.