tolua++その1(構成)

http://www.codenix.com/~tolua/

luaの便利c++バインダーであるところのtolua++についてのメモ。

構成

tolua++は、tolua++コマンドとそのコマンドで生成したコードをコンパイルしてリンクするのに必要なライブラリ部分でできている。こんな感じ

  • ライブラリ部
include/tolua++.h
src/lib/tolua_event.c
src/lib/tolua_is.c
src/lib/tolua_map.c
src/lib/tolua_push.c
src/lib/tolua_to.c

tolua++でラップしたコードを使うライブラリと同じコンパイラでビルドしたものがよいので、vcならプロジェクトに追加してしまうのが手っ取り早い。gccならスタティックライブラリにする(趣味)
  • コマンド部
src/bin/tolua.c
src/bin/toluabind.c
src/bin/toluabind.h

これに上記のライブラリ部分とlua本体をリンクする。
gccだと 
-ltolua++ -llua
といった感じに。

toluaコマンド

toluaコマンドの本体は、luaスクリプトで記述されている。
toluaコマンドでtoluaのluaスクリプトをcの実行ファイルに埋め込んでビルドするとtoluaコマンドになる。toluaコマンドでtoluaコマンドを生成するわけですな。そのtolua用の入力がsrc/bin/tolua_scons.pkgで

$lfile "src/bin/lua/compat-5.1.lua"
$lfile "src/bin/lua/compat.lua"
$lfile "src/bin/lua/basic.lua"
$lfile "src/bin/lua/feature.lua"
$lfile "src/bin/lua/verbatim.lua"
$lfile "src/bin/lua/code.lua"
$lfile "src/bin/lua/typedef.lua"
$lfile "src/bin/lua/container.lua"
$lfile "src/bin/lua/package.lua"
$lfile "src/bin/lua/module.lua"
$lfile "src/bin/lua/namespace.lua"
$lfile "src/bin/lua/define.lua"
$lfile "src/bin/lua/enumerate.lua"
$lfile "src/bin/lua/declaration.lua"
$lfile "src/bin/lua/variable.lua"
$lfile "src/bin/lua/array.lua"
$lfile "src/bin/lua/function.lua"
$lfile "src/bin/lua/operator.lua"
$lfile "src/bin/lua/template_class.lua"
$lfile "src/bin/lua/class.lua"
$lfile "src/bin/lua/clean.lua"
$lfile "src/bin/lua/doit.lua"

$[
local err,msg = pcall(doit)
if not err then
 local _,_,label,msg = strfind(msg,"(.-:.-:%s*)(.*)")
 tolua_error(msg,label)
 print(debug.traceback())
end
$]

となっている。toluaの用の入力をパッケージファイルと呼ぶ。パッケージファイルはだいたいc++のヘッダファイルとして記述できて、tolua独自の命令を記述するときは$を行頭に置く。$lfileはluaスクリプトの実行になる。luaのdofile関数的な意味になる。ただし対象のスクリプトはluacでコンパイルされてcの配列として生成されたソースに埋め込まれる。実行されるタイミングは、たぶんtoluaコマンドで生成されたソースのtolua_xxxx_open関数を呼んだとき。上記のパッケージファイルの場合は、各スクリプトで関数の定義なんかをして、最後にdoit.luaスクリプトに記述されていたdoit関数を実行している。

toluaコマンドのビルド

toluaコマンドは、

ということになっている。具体的には下記のようにビルドされる

  1. libtolua++.aをビルド
  2. tolua_bootstrapコマンドをtoluaされたソース(toluabind_default.c)とlibtolua++を使ってビルド
  3. tolua_bootstrapでsrc/bin/lua/*.luaからソースを生成
  4. toluaコマンド(真)をtolua_bootstrapされたソース(toluabind.c)とlibtolua++を使ってビルド

多少ややこしいのでsconsでビルドスクリプトが書かれてしまった(そのせいでビルドの敷居がちょっとあがっている)。

toluaのソースアーカイブには、最初からtoluaされたソース(toluabind.c)が含まれているので無意味な工程が入っているように見えるが、src/bin/luaにあるスクリプトをカスタマイズするチャンスを作るためにそうなっている。
で、toluaでtoluaを作るんだったら最初のtoluaはどうすんだということになるのだがtoluaしないでluaスクリプトととして使えば問題無いはず。次回で、tolua本体のluaスクリプトの解読とカスタマイズ(lua_CFunction型の関数だけ処理を変えるなど)について触れる予定。

scons無しでビルドする例

x86_64-w64-mingw32 gcc-4.5.2でlua-5.1.4(lua.hとかliblua.a)がインストール済みの環境で実験した。

Makefile

all:
        make -f libtolua++.make
        make -f bootstrap.make
        tolua_bootstrap -C -H src/bin/toluabind.h -o src/bin/toluabind.c -n tolua src/bin/tolua_scons.pkg
        make -f tolua.make

clean:
        make -f libtolua++.make clean
        make -f bootstrap.make clean
        rm -f src/bin/toluabind.{h,c}
        make -f tolua.make clean

libtolua++.make

OBJS=src/lib/tolua_event.o src/lib/tolua_is.o src/lib/tolua_map.o src/lib/tolua_push.o src/lib/tolua_to.o
CFLAGS=-I./include
TARGET=libtolua++.a

all: $(TARGET)

$(TARGET): $(OBJS)
        ar r $@ $^

.c.o:
        gcc -c -o $@ $(CFLAGS) $<

clean:
        rm -f $(TARGET) $(OBJS)

bootstrap.make

OBJS=src/bin/tolua.o src/bin/toluabind_default.o
CFLAGS=-I./include
LDFLAGS=-L. -ltolua++ -llua
TARGET=tolua_bootstrap.exe

all: $(TARGET)

$(TARGET): $(OBJS)
        gcc -o $@ $^ $(LDFLAGS)

.c.o:
        gcc -c -o $@ $(CFLAGS) $<

clean:
        rm -f $(TARGET) $(OBJS)

tolua.make

OBJS=src/bin/tolua.o src/bin/toluabind.o
CFLAGS=-I./include
LDFLAGS=-L. -ltolua++ -llua
TARGET=tolua++.exe

all: $(TARGET)

$(TARGET): $(OBJS)
        gcc -o $@ $^ $(LDFLAGS)

.c.o:
        gcc -c -o $@ $(CFLAGS) $<

clean:
        rm -f $(TARGET) $(OBJS)