にゃははー

はへらー

bjam AdC jp 2011 5日目

Boost.勉強会 #7東京で同士を募ったらATNDの参加者が0人増えてました!!!!!やったねたえちゃん!!!


よくねぇよッッッッ!!!!!!!!!!!!!

めんどいんで進みます。

aliasモジュール

ある程度プロジェクトが大きくなってくるとビルドターゲットが増えてきます。通常、obj/lib/exe rule等を用いていれば特に問題はないですが、あるグループ単位でビルドを走らせたいとか、テストをまとめて走らせたいとなってくると困ります。

そこでaliasモジュールを使います。

シグネチャは以下の通り

rule alias ( name : sources * : requirements * : default-build * : usage-requirements * )

簡単に使うとこんな感じ

obj hoge : hoge.cpp ;
obj fuga : fuga.cpp ;
obj piyo : piyo.cpp ;

# libにするほどでもないけど各所で使われるからまとめとく
alias foo : hoge fuga piyo ;

exe bar : bar.cpp foo ;
exe baz : baz.cpp foo ;

ちなみにaliasモジュールはbuilt-inなのでimportする必要はありません。

あとは子プロジェクトのターゲットをまとめたりとか

projects = sub1 sub2 sub3 ;
alias outputs : /$(projects)//outputs ;

テストを通常ビルドから切り離す

ライブラリを書く上でテストは切り離せないものです。切り離したらそれはライブラリではなくバイナリの塊です。

ところで皆さんは依存関係とかでmakeしたライブラリはちゃんとmake checkでテストしてますか?特にbinutils等はちゃんとテストしたほうがいいです。
そしてライブラリ書いたらテストしてますか?出来ればテストケースを先に書いてからライブラリを書ければいいのですがそういかない場合も多いかと思います。せめて単体テストをあとから追加しとくぐらいはして欲しいです。

そしてmake checkをすると多くの人は気づくと思うのですが、makeではなくmake checkをしたときにだけテスト用のバイナリがコンパイルされます。しかしbjamでテスト用のバイナリ書いてexe ruleとかに突っ込むと問答無用でビルドされてしまいます。
正直ライブラリのビルドはテストまで勝手にやってくれていいと思うのですが、テストケースが爆発すると何時間もかかるようになってしまってユーザーからするとちょっとウザイです...

余談ですが、libpplって皆さん知ってますか?GCCビルドしまくってる皆さんなら知ってると思います。何やってるか知らないですが。
ところでlibpplのテスト走らせたことありますか?やったこと無い人は走らせてみて絶望してください。特にクォータがある環境とか最高です。大学のマシンでクォータが3GBぐらいだとドンピシャです。

そこでテストのターゲットだけデフォルトでビルドされない様に分離しましょう。このターゲット名をmakeのと同様にcheckとします。

例えばライブラリが

lib foo : hoge.cpp fuga.cpp piyo.cpp ;

だったとしましょう。

それに対してテストが

exe test1 : test1.cpp foo ;
exe test2 : test2.cpp foo ;
...

と続いているとします。

このままだと libfoo.a と test1 test2 ... が生成されるだけです。また生成したテストも実行されません。生成を阻止するのはexplicit ruleを使います。
バイナリの実行はboostjpのTips - ビルドツールに書かれています。まとめられているせいでAdvent Calendarの1エントリ分ぐらい損してます。まぁ書いたの私ですが。

まぁこれを元にテストを実行できるようにしてみましょう。ついでに面倒なので1つのruleにまとめます。

import notfile ;
actions exec-test
{
	$(2)
}
rule run-test( name : sources * )
{
	exe $(name)-exe : $(sources) ;
	notfile $(name) : @exec-test : $(name)-exe ;
	explicit $(name)-exe ;
	explicit $(name) ;
}

run-test test1 : test1.cpp foo ;
run-test test2 : test2.cpp foo ;
...

となります。ビルドターゲット毎にexplicit ruleを適用する必要があることに注意してください。

あとはおわかりかと思いますが各test*をcheckというターゲットにまとめます。

alias check : test1 test2 ... ;
explicit check ;

explicitを忘れずに。

まとめ

プロジェクトが大きくなったらaliasを使って適当な粒度にまとめ直すといいです。
あと知ってる人はなんでtestingモジュール使わないんだと思うかもですが、Advent Calendarのネタを奪うのはやめてください。なので次はtestingモジュールについてやります。

明日については何も言わないことにします。