なぜホームページを作るのですか?作るだけでは終わらない千客万来亭

D言語 tango shared library

以前こんな記事で、D言語でも簡単に so を生成できるという話を書きました。

今わたしが書いているほとんどのD言語によるプログラムでは、phobos ではなく tango を使用していることもあって、この tango の so 化に挑戦してみました。

まだうまく行ってないのですが、覚書として書いておくことにします。

tango の shared library 化

まずは、こちらのページからソースコード一式をダウンロードしてきます。

以前もあてたパッチで最新のdmdでコンパイルが通るように修正します。

まずは、so 作成に必要なファイル群を抽出して、コンパイル、そして so を作成するところまでを行なうスクリプトを以下に。

#!/bin/sh
CSRC=`find tango -name '*.c' -print | egrep -v '(/ldc/|/gdc/|/windows/deh.c)'`
DSRC=`find tango -name '*.d' -print | egrep -v '(/darwin/|/solaris/|/freebsd/|/win32/|/gdc/|/ldc/|/gc/stub/gc.d|/Win32.d)'`
for i in $CSRC
do
    echo gcc -c -O2 -fPIC $i
    gcc -c -O2 -fPIC $i
done
for i in $DSRC
do
    echo dmd -c -op -fPIC -inline -release -O -I. -Itango/core -Itango/core/vendor -version=Tango $i
    dmd -c -op -fPIC -inline -release -O -I. -Itango/core -Itango/core/vendor -version=Tango $i
done
gcc -shared -Wl,-soname,libtango.so.0.99.9 -o libtango.so.0.99.9 `find . -type f -name '*.o' -print` -Xlinker -lz -lbz2
find . -type f -name '*.o' -exec rm {} \;

これを実行すると、以下のようなエラーを吐いてリンクに失敗します。

/usr/bin/ld: libtango.so.0.99.9: version node not found for symbol _d_throw@4
/usr/bin/ld: failed to set dynamic section sizes: Bad value
collect2: ld はステータス 1 で終了しました

_d_throw@4 で調べて歩くと、extern (Windows) がまずいという記述が見つかりましたので、これを修正。

--- tango-0.99.9/tango/core/rt/compiler/dmd/posix/deh.d 2009-11-19 09:33:49.000000000 +0900
+++ tango-0.99.9-p/tango/core/rt/compiler/dmd/posix/deh.d       2010-07-14 21:11:12.229090955 +0900
@@ -154,7 +154,7 @@
  * Throw a D object.
  */

-extern (Windows) void _d_throw(Object *h)
+extern (C) void _d_throw(Object *h)
 {
     uint regebp;

これで、一応 Shared Object としてリンクすることはできました。

次にこの so を使って、簡単なサンプルを作成してみます。

import tango.io.Stdout;

void main() {
    Stdout("Hello World!").newline;
}

これを以下のようにして、コンパイルとリンク。先ほど作った libtango.so.0.99.9 を libtango.so にシンボリックリンクしておきます。

$ ln -s libtango.so.0.99.9 libtango.so
$ dmd -I. -c main.d
$ gcc main.o -o main -Xlinker -L. -ltango -lpthread -ldl -lm

これで、コンパイル、リンクが通って、main なる実行ファイルが出来上がるのですが、残念ながら実行すると SIGSEGV で落ちてしまいます。

日本語の情報は発見できず。英語の情報を探していますが、まだ解決したというものを見つけられていません。

さて、まじめにデバッグしてみないとならないかな。。。