以前、jamによるjavaにチャレンジして失敗してしまったので、ARMも動作対象となっているmonoで.netを動かしてみようと実験。
量が多いのでdistccを使いました。ホスト側はクロスコンパイル用の自作PC(CentOS 5.2)を使います。
本家よりソース"mono-1.9.1.tar.bz2"を頂いてきて適当な場所で展開。更にビルドにはpkg-configやglibが必要だそうなので予め入れておきます(私の環境にはVineから拝借したものがRPMで既に入っているので、それを利用)。X-Window等は入っていませんからWindowsFormやSystem.Drawingの利用はきっぱり諦めますw(従ってgdi+のライブラリlibgdiplusもビルドしない)。ソースの分量も多いのでdistccが使えるようにしておきます(ネイティブコンパイラで放置でも構いませんw):
$ export PATH=/usr/local/develop/distcc:$PATH
$ export DISTCC_HOSTS=192.168.XX.YY ←distccdが動作しているホスト側のIP
$ ./configure --prefix=/usr/local/develop --with-tls=pthread --disable-mcs-build --without-x --with-static_mono=yes
:
:(中略)
mcs source: $(top_srcdir)/mcs
olive source:
GC: included
TLS: pthread
SIGALTSTACK: yes
Engine: Building and using the JIT
2.0 Beta: yes
2.1 Alpha: yes
JNI support: IKVM Native
libgdiplus: assumed to be installed
zlib: system zlib
oprofile: no
$ make
$ make install
$ ldconfig
これでランタイムを除くARM用のバイナリは完成。
次に、ホスト側でもx86用のバイナリを作成し、こちらでランタイムもビルドします:
$ ./configure --prefix=/usr/local/develop --with-tls=pthread
$ make
$ make install DESTDIR=/some/where ←仮にインストールする場所を適当に設定
$ cd /some/where/usr/local/develop/lib
$ tar cvzf mono-runtime.tar.bz2 mono/ ←ランタイムだけtarボールにしてLS-GLに持っていく準備
ホスト側で作成されたランタイム(tarボール)だけをLS-GLに持っていきます:
$ cd /usr/local/develop/lib
$ tar xvjf mono-runtime.tar.bz2
これで一通り作業が出来ました。
お決まりのHelloWorldで動作確認してみます:
$ vim HelloWorld.cs
class HelloWorld {
static void Main() {
System.Console.WriteLine("Hello World!");
}
}
$ mcs HelloWorld.cs ←C#をコンパイル
$ mono HelloWorld.exe ←出来上がったexeを実行
Hello World!
動いたようです。
もうちょっと手の込んだ動作確認をしてみます。自宅のLS-GLにはブログ用のMySQLが稼動しているので、monoのADO.NETから接続してみます。MySQL用のADO.NETドライバは本家にて公開されています。Connectors/Netのインストーラー無し(現時点での最新は5.2)のzipファイルをダウンします。zipファイルを展開するとbin/にMySql.Data.dllが含まれているので、それをLS-GLの適当な場所にコピーします。次にMySql.Data.dllをmono(.net framework)のグローバルアセンブリキャッシュに登録します:
$ gacutil -i /path/to/MySql.Data.dll ←グローバルアッセンブリキャッシュに登録
MySQLにテスト用のデータベースとユーザを適当に登録しておきます(詳細は省略、例えばデータベースはtest_db、ユーザはtest_user@localhost、パスワードもtest_user、テーブルはtest_tableとか)。
$ vim TestMySql.cs
using System;
using System.Data;
using MySql.Data.MySqlClient;
public class TestMySql
{
public static void Main(string[] args)
{
string connectionString = "Server=localhost; Database=test_db;User ID=test_user; Password=test_user; Pooling=false";
IDbConnection cn = new MySqlConnection(connectionString);
cn.Open();
IDbCommand cmd = cn.CreateCommand();
cmd.CommandText = "SELECT item1,item2 FROM test_table";
IDbDataAdapter ad = new MySqlDataAdapter();
ad.SelectCommand = cmd;
DataSet ds = new DataSet("test");
ad.Fill(ds);
cn.Close();
ad = null;
cmd = null;
cn = null;
foreach (DataRow dr in ds.Tables[0].Rows) {
Console.WriteLine("item1 = " + (string) dr[0] + " item2 = " + (string) dr[1]);
}
ds.Dispose();
ds = null;
}
}
MySql.Data.dllは.net framework 2.0用なのでmonoのコンパイルも2.0用(gmcs)で行います:
$ gmcs TestMySql.cs -r:System.Data.dll -r:/path/to/MySql.Data.dll
$ mono TestMySql.exe
item1 = aaaaa item2 = AAAAA
item1 = bbbbb item2 = BBBBB
おぉ、動いた!w これにはちょっと感動。
xsp、mod_monoがあればApacheでASP.NETも可能ということらしいので、monoの本家よりxsp-1.9.1.tar.bz2、mod_mono-1.9.tar.bz2を頂いてきます。
まずはxspのソースを展開し、ビルドします:
$ ./configure --prefix=/usr/local/develop
$ make
$ make install
ところが、xsp-1.9.1/test/1.1/webcontrols/dbpage_test_setup.csのビルド中にエラーが発生:
Unhandled Exception: Mono.Data.SqliteClient.SqliteExecutionException: SQL logic error or missing database
at Mono.Data.SqliteClient.SqliteCommand.ExecuteStatement (IntPtr pStmt, System.Int32& cols, System.IntPtr& pazValue, System.IntPtr& pazColName) [0x00000]
at Mono.Data.SqliteClient.SqliteCommand.ExecuteStatement (IntPtr pStmt) [0x00000]
at Mono.Data.SqliteClient.SqliteCommand.ExecuteReader (CommandBehavior behavior, Boolean want_results, System.Int32& rows_affected) [0x00000]
at Mono.Data.SqliteClient.SqliteCommand.ExecuteNonQuery () [0x00000]
at App.Main () [0x00000]
いったい何のエラーなのか?ということで調べてみるとファイルの権限云々という話もちらほらあったので、同じディレクトリのdbpage1.sqliteやdbpage2.sqliteのファイルアクセス権限を777にしてもう一度ビルドしたら最後まで行きました。しかし、エラーが発生した時点では既にdbpage_test_setup.exeのビルドには成功しているようなので、単純に2回目はmakeがスルーしてしまっただけかもしれません…。細かい原因究明はまた今度ということで今回はそのまま先に進みすw
次にmod_monoも同様にソースを展開してビルドしますが、Apache2のincludeパスを発見出来ないようなので環境変数で指定しておきます。尚、configureがLS-GLに元々入っているapache1.3のapxsに反応してしまうので/usr/local/apacheのapxsをリネーム等しておきます:
$ export CFLAGS="-I/usr/local/develop/include/apache2"
$ ./configure --prefix=/usr/local/develop
$ make
$ make install
これでビルドは完了。
mod_monoが動くようにApache側の設定を行います。mod_mono用のconfはmake installでインストールされているので(ちょっとVine設定のApacheとディレクトリが異なったので手で移動させましたがw)、デモ画面がアクセス出来るようにhttpd.confの設定だけを行います:
Alias /demo "/usr/local/develop/lib/xsp/test"
MonoApplications "/demo:/usr/local/develop/lib/xsp/test"
編集が出来たらApache2を再起動させます。
ブラウザで/demoにアクセスします・・・・・・・・・お、遅い;; それでもサンプルは動くようです。中でもカレンダーはSystem.Drawingを使っているようで当然このLS-GLでは動かせないのですが、表示されるエラー画面が本物そっくりで笑えました。
それにしても、LS-GLでASP.NETが、それなりに動くのは楽しいですねw
まだ触り程度の動作確認ですし、monoの使い方もよくわかっていませんがLS-GLで.netが動いたのには驚きました。