BoostBuild-pre

Download Report

Transcript BoostBuild-pre

Boost.Build
2010年10月23日
Boost.勉強会 #3 関西
郵便はみがき
1
自己紹介
郵便はみがき
• y-hamigaki(はてな) yhamigaki(Twitter)
• ブログ「かそくそうち」
http://d.hatena.ne.jp/y-hamigaki/
• フリーソフト「Dante98 for Windows」
• ライブラリ「Hamigaki C++ Libraries」
2
概要
•
•
•
•
•
はじめに
Boost.JamとJam言語
Boost.Build
Tips
まとめ
3
はじめに
4
Boost.Buildとは
•
•
•
•
•
Boostで用いられるビルドシステム
マルチプラットフォーム、マルチコンパイラ
Jam言語による柔軟な制御
「make + 簡易configure」のようなもの
モジュールによる機能拡張
5
Boost.BuildとBoost.Jamの関係
• Boost.Jamがビルドツール
• Boost.BuildはBoost.Jamとそのスクリプト集
• 狭義にはスクリプト集だけを指して
Boost.Buildと呼ぶことも
6
Boost.JamとJam言語
7
Boost.Jam (bjam)
•
•
•
•
•
•
Perforce Jam→FT Jam→Boost.Jam
内蔵のJambaseをBoost向けにカスタマイズ
bjamをjamにリネームするとJamとして動作
言語機能の追加(module, class, …)
Pythonとの連動
${BOOST_ROOT}/tools/jam/src
${BOOST_ROOT}/tools/build/v2/engine/src
8
Perforce Jam
•
•
•
•
•
マルチプラットフォームのビルドツール
Jam言語で依存関係やオプションを設定
Jambaseが各コンパイラを知っている
ヘッダファイルの依存関係を自動解析
最新バージョンは2.5 (2003年4月)
9
Makefileの例
proga: data.o main.o io.o
cc data.o main.o io.o -o proga
data.o: data.c data.h
cc -c data.c
main.o: data.h io.h main.c
cc -c main.c
io.o: io.h io.c
cc -c io.c
http://www.perforce.com/jam/jam.html
10
Jamfileの例
Main proga : data.c main.c io.c ;
http://www.perforce.com/jam/jam.html
11
Jam言語
•
•
•
•
•
チューリング完全
データ型は文字列のリストのみ
トークンは空白文字で区切る
#以降改行までがコメント(トークン中は無効)
大文字/小文字は区別する
12
Hello, world!
#hello.jam
EXIT␣Hello,␣world!␣;
$ jam –f hello.jam
Hello, world!
$
13
変数
X␣=␣Boost␣;␣#変数Xに文字列「Boost」を代入
ECHO␣$(X)␣;␣#「Boost」を出力
Y␣=␣Build␣Jam␣;␣#Yに「Build」と「Jam」代入
ECHO␣$(Y)␣;␣#「Build Jam」を出力
ECHO␣$(X)␣$(Y)␣;␣#「Boost Build Jam」を出力
ECHO␣$(X).$(Y)␣;␣#「Boost.Build Boost.Jam」
14
変数展開
修飾子
意味
[n]
[n-m]
:U
:D
n番目の要素(基数=1)
n番目からm番目の要素
大文字にする
ディレクトリ名を取り出す
:B
:S
:S=ext
ベース名を取り出す
拡張子を取り出す
拡張子をextに置換する
:T
「/」を「\」に置換する
要素をdelimで区切って連結する
:J=delim
15
パス名
dir1/dir2 /
ディレクトリ名
:D
basename
ベース名
:B
.ext
(member)
拡張子 アーカイブメンバ
:S
:M
ph␣=␣dir1/dir2/basename.ext(member)␣;
ECHO␣$(ph:BS=.cpp)␣;␣#「basename.cpp」
16
ルール(関数)
rule␣hello
{
ECHO␣Hello,␣world␣;
}
hello␣;␣#「Hello, world!」を出力
17
引数
rule␣greet
{
ECHO␣"Hello,␣$(1)-$(2)."␣;
}
greet␣Taro␣:␣kun␣; ␣#「Hello, Taro-kun.」
greet␣Naoko␣:␣san␣;␣#「Hello, Naoko-san.」
18
名前付き引数(bjam拡張)
rule␣greet␣(␣name␣:␣postfix␣)
{
ECHO␣"Hello,␣$(name)-$(postfix)."␣;
}
greet␣Taro␣:␣kun␣; ␣#「Hello, Taro-kun.」
greet␣Naoko␣:␣san␣;␣#「Hello, Naoko-san.」
19
引数の制約(bjam拡張)
rule␣hoge␣(␣A␣*␣:␣B␣+␣:␣C␣?␣:␣D␣)
引数
A*
B+
C?
D
リストのサイズ
0以上
1以上
0か1
1
20
戻り値
rule␣greet-msg␣(␣name␣:␣postfix␣)
{
return␣"Hello,␣$(name)-$(postfix)."␣;
}
#「Hello, Taro-kun.」を出力
ECHO␣[␣greet-msg␣Taro␣:␣kun␣]␣;
21
if文
if␣$(X)
{
ECHO␣OK␣;␣#Xが真の場合
}
else
{
ECHO␣NG␣;␣#Xが偽の場合
}
22
条件式
条件式
a
!a
a=b
a != b
a <= b
a in b
a && b
a || b
意味
aに空でない要素があれば真
aに空でない要素がなければ真
aとbの要素が同じならば真
a とbに違う要素があれば真
辞書順でaがb以下なら真
aの要素が全てbに含まれていれば真
aとbが真ならば真
aかbが真ならば真
23
for文
for␣X␣in␣one␣two␣three
{
ECHO␣$(X)␣;
}
one
two
three
24
while文
X␣=␣one␣two␣three␣;
while␣$(X)
{
ECHO␣$(X[1])␣;␣#先頭要素を出力
X␣=␣$(X[2-])␣;␣#後ろの要素で再設定
}
25
モジュール(bjam拡張)
module␣foo {
rule␣hello␣{␣ECHO␣hello␣;␣}
}
module␣bar␣{
IMPORT␣foo␣:␣hello␣:␣bar␣:␣foo.hello␣;
foo.hello ;
}
26
サンプルプログラム(剰余)
rule␣mod␣(␣A␣B␣)␣{
local␣C␣=␣$(A)␣;
while␣$(C)␣>␣-:␣{
A␣=␣$(C)␣;
C␣=␣[␣CALC␣$(A)␣-␣$(B)␣]␣;
}
return␣$(A)␣;
}
27
サンプルプログラム(FizzBuzz)
N=1;
while $(N) != 101 {
if [ mod $(N) 15 ] = 0 { ECHO FizzBuzz ; }
else if [ mod $(N) 3 ] = 0 { ECHO Fizz ; }
else if [ mod $(N) 5 ] = 0 { ECHO Buzz ; }
else { ECHO $(N) ; }
N = [ CALC $(N) + 1 ] ;
}
28
actions
• ルールを呼び出すと同名actionsがビルドコマン
ドとしてセットされる
• 第一引数がターゲット、第二引数がソース
rule␣copy␣(␣target␣:␣source␣)␣{␣}
actions␣copy␣{
cp␣$(>)␣$(<)
}
copy␣out.txt␣:␣in.txt␣;
29
DEPENDS
• ビルド依存関係を指定する組み込みルール
• 既定のターゲットは「all」
rule␣copy␣(␣target␣:␣source␣)␣{
DEPENDS␣$(target)␣:␣$(source)␣;
DEPENDS␣all␣:␣$(target)␣;
}
30
Clean
• ターゲットを削除するルール(Jambaseで定義)
• 通常、ターゲット名はclean
rule␣copy␣(␣target␣:␣source␣)␣{
DEPENDS␣$(target)␣:␣$(source)␣;
DEPENDS␣all␣:␣$(target)␣;
Clean␣clean␣:␣$(target)␣;
}
31
jamコマンド
• 「all」をビルド
jam
• 「out.txt」をビルド
jam out.txt
• クリーン
Jam clean
32
Boost.Build
33
Boost.Build Version1
• JambaseをBoost向けに改良
• ツールセットやビルドオプション(ABI)の違い毎
に別ディレクトリへ出力
↓
一度に複数のツールセットでビルド可能
• 環境設定は環境変数とコマンドライン引数
34
Boost.Build Version2 (BBv2)
•
•
•
•
Boost 1.34.0以降の標準ビルドシステム
設定ファイルでツールセット毎に環境設定
C/C++以外のツールにも対応、拡張可能
${BOOST_ROOT}/tools/build/v2
35
BBv2の例
#Jamroot
exe␣proga␣:␣data.cpp␣main.cpp␣io.cpp␣;
36
BBv2実行例
$ bjam toolset=gcc
...found 17 targets...
...updating 7 targets...
common.mkdir bin
common.mkdir bin/gcc-4.3.4
common.mkdir bin/gcc-4.3.4/debug
gcc.compile.c++ bin/gcc-4.3.4/debug/data.o
gcc.compile.c++ bin/gcc-4.3.4/debug/main.o
gcc.compile.c++ bin/gcc-4.3.4/debug/io.o
gcc.link bin/gcc-4.3.4/debug/proga.exe
...updated 7 targets...
37
プロパティ
フィーチャー
意味
値
toolset
使用するツールセット
msvc, gcc, darwin, …
variant
ビルド構成
debug, release, profile
threading
スレッド環境
multi, single
link
生成するライブラリのリンク方法
shared, static
runtime-link
標準ライブラリのリンク方法
shared, static
include
追加のインクルードパス
任意
define
追加のマクロ定義
任意
library-path
追加のライブラリパス
任意
cxxflags
追加のコンパイラオプション
任意
linkflags
追加のリンカオプション
任意
address-model
対象となるアドレスモデル
32, 64
38
環境設定
•
•
•
•
jamスクリプトによる設定ファイル
site-config.jam→マシン単位の設定
user-config.jam→ユーザー単位の設定
ホームディレクトリ等に配置
39
user-config.jamの例
module␣{
BZIP2_SOURCE␣=␣C:/src/bzip2-1.0.6␣;
ZLIB_SOURCE␣=␣C:/src/zlib-1.2.5␣;
}
using␣msvc␣:␣10.0␣;
using␣msvc␣:␣9.0␣;
using␣gcc␣:␣:␣C:/mingw/bin/g++.exe␣;
import␣python-config␣;
40
プロジェクト設定
• ビルド設定をディレクトリ内で共有
• サブディレクトリへも反映
• プロジェクトを利用する側の設定も指定
(usage-requirements)
41
projectルールの引数
名前
source-location
requirements
usagerequirements
default-build
build-dir
意味
ソースファイルの場所
ビルド要件となるプロパティのリスト
参照先プロジェクトに要求されるプロ
パティのリスト
既定のプロパティのリスト
出力先ディレクトリ
42
プロパティの指定方法
• フィーチャーthreadingをmultiにする
<threading>multi
• ツールセットがmsvcならばHOGE=1を定義
<toolset>msvc:<define>HOGE=1
• ツールセットがgccでOSがWindowsなら静的リ
ンクを用いる
<toolset>gcc,<os>NT:<link>static
43
プロジェクトの例
project␣test-proj
:␣source-location␣src
:␣requirements␣<include>$(BOOST_ROOT)
:␣usage-requirements␣<include>.
:␣default-build␣debug
:␣build-dir␣bin
;
44
プロジェクトの参照
参照先プロジェクトのusage-requirementsをプロ
ジェクトのrequirementsに反映させる
use-project␣/boost␣:␣$(BOOST_ROOT) ;
project␣my-proj
:␣requirements␣<library>/boost//headers
;
45
ターゲット
次の形式のルールでビルドターゲットを定義する
rule␣ルール名␣(
main-target-name␣:
sources␣+␣:
requirements␣*␣:
default-build␣*␣:
usage-requirements␣*␣)
46
ターゲットルール
ルール
exe
lib
obj
alias
用途
実行ファイル
ライブラリファイル
オブジェクトファイル
別名(ヘッダのみのライブラリにも利
用できる)
47
単体テスト
ルール
compile
compilefail
link
link-fail
run
run-fail
意味
コンパイルに成功することを確認する
コンパイルに失敗することを確認する
コンパイル、リンクに成功することを確認する
コンパイルに成功し、リンクに失敗することを確認す
る
コンパイル、リンク、実行に成功することを確認する
コンパイル、リンクに成功し、実行に失敗することを
確認する
48
Boost.Test使用例
import␣testing␣;
use-project␣/boost␣:␣$(BOOST_ROOT)␣;
run␣test.cpp␣:␣:␣:
<define>BOOST_ALL_NO_LIB=1
<library>/boost/test//boost_unit_test_framework
;
49
デバッグ
• クラッシュしたらJITデバッガを起動する
• coreをgdb等でデバッグ
• testing.launcherフィーチャー
50
Tips
51
modules.peek/modules.poke
import␣modules␣;
#モジュールm1の変数Xの値を取得
x␣=␣[␣modules.peek␣m1␣:␣X␣;␣]␣;
#モジュールm2の変数Yに値を設定
modules.poke␣m2␣:␣Y␣:␣$(x)␣;
#空のモジュール名はグローバル
os␣=␣[␣modules.peek␣:␣OS␣;␣]␣;
52
path.glob
rule␣glob␣(
dirs␣*␣:
patterns␣+␣:
exclude-patterns␣*␣)
引数
dirs
patterns
exclude-patterns
意味
検索するディレクトリのリスト
リストに含めるファイル名のパターン
リストから除外するファイル名のパターン
53
path.globの使用例(1)
import␣path␣;
import␣testing␣;
lib␣mylib␣:␣[␣path.glob
.␣:
*.cpp␣:
*_test.cpp␣main.cpp
]␣;
exe␣myapp␣:␣main.cpp␣mylib␣;
54
path.globの使用例(2)
local␣tests␣=␣;
for␣local␣t␣in
[␣path.glob␣.␣:␣*_test.cpp␣]␣{
run␣$(t)␣mylib␣:␣:␣:␣:␣$(t:B)␣;
explicit␣$(t:B)␣;
tests␣+=␣$(t:B)␣;
}
alias␣test␣:␣$(tests)␣;␣explicit␣test␣;
55
警告メッセージ抑制
import␣path␣;
local␣broot␣=
[␣modules.peek␣:␣BOOST_ROOT␣]␣;
local␣bdir␣=␣[␣path.make␣$(broot)␣]␣;
for␣local␣lib␣in␣graph␣mpi␣python␣regex␣{
module␣Jamfile<$(bdir)/libs/$(lib)/build>␣{
rule␣ECHO␣{␣}
}
}
56
conditionalフィーチャー
rule user-interface-gui ( properties * ) {
if <toolset>gcc in $(properties) {
return <linkflags>-mwindows ;
} else return <user-interface>gui ;
}
exe gui : gui.cpp :
<conditional>@user-interface-gui ;
57
ヘッダ生成
import make ;
actions compile_vs40 {
fxc.exe /E VS /T vs_4_0 /Fh $(<) /Vn $(<:B) $(>)
}
make test_vs.h : test.fx : @compile_vs40 ;
exe test : test.cpp :
<implicit-dependency>test_vs.h ;
58
Python呼び出し(Python側)
#hello.py
def greet(args):
print args
return args[0]
59
Python呼び出し(bjam側)
#Jamfile
PYTHON_IMPORT_RULE
hello␣:␣greet␣:
$(__name__)␣:␣hello.greet␣;
EXIT␣[␣hello.greet␣"abc def"␣ghi␣]␣;
60
Python呼び出し(実行例)
% bjam
['abc def', 'ghi']
abc def
%
61
まとめ
62
Boost.Buildの今後
現在の問題点
• データ構造が貧弱なので遅い
• スクリプトがトリッキーなためメンテナ不足
↓
JamスクリプトをPythonに移行(7倍高速化)
63
参考サイト
• Perforce Jam
http://www.perforce.com/jam/jam.html
• Boost.Build バージョン2 チュートリアル
http://www12.ocn.ne.jp/~dante98/bbv2tutorial.html
• Hamigaki C++ Libraries 付録 A
http://hamigaki.sourceforge.jp/doc/html/bbv
2.html
64