続・ruby 1.9.1-p0 @ Visual C++ 2005
rubygems Hpricot はバイナリだった
ようやく rubygems が動く環境も整備できたので、息切れしつつ hpricot をインストール。テストのためにアプリを動かしてみると、msvcrt-ruby18.dll がねーよというエラーが出てくれた。どうやら、rubygems の Hpricot(mswin32) は ソースコードじゃなくてバイナリで、しかも ruby 1.8 用らしい。
仕方ないので、Hpricot の公式サイトにアクセスしてみると、Not Found。どうして・・・? ここで諦めては努力が水泡に帰してしまうので、hpricot-0.6.164.gem で検索して、強引にゲットしてきた。
早速 gem に食べさせてみると、zlib と違って今度は本当にビルドできない。なにやら RArray の ptr とか len がないとかエラーを吐いている。1.8 → 1.9 で RArray の仕様が変更されたんだろう。
gem から spec と ソースを抜いて 1.9 仕様に書き換えた。
--- data/ext/fast_xs/fast_xs.c.old 2009-01-10 12:48:01.000000000 +0900 +++ data/ext/fast_xs/fast_xs.c 2009-01-10 12:48:33.934417600 +0900 @@ -166,14 +166,14 @@ array = RARRAY(rb_rescue(unpack_utf8, self, unpack_uchar, self)); - tmp = array->ptr; - for (i = array->len; --i >= 0; tmp++) + tmp = RARRAY_PTR(array); + for (i = RARRAY_LEN(array); --i >= 0; tmp++) s_len += escaped_len(NUM2INT(*tmp)); c = s = alloca(s_len + 1); - tmp = array->ptr; - for (i = array->len; --i >= 0; tmp++) + tmp = RARRAY_PTR(array); + for (i = RARRAY_LEN(array); --i >= 0; tmp++) c += escape(c, NUM2INT(*tmp)); *c = '\0';
これを gem にパックし直して、もう一度。
fast_xs.obj : error LNK2019: 未解決の外部シンボル '_ruby_digitmap' ...
どういうことなの・・・?試しに VC++8 IDE で _ruby_digitmap を参照するコードを書いて検証してみた。
int main() { extern const char ruby_digitmap[]; printf("%d\n", ruby_digitmap[0]); return 0; }
追加ライブラリに msvcr80-ruby191.lib を指定してビルドしてみると、全く同じエラーが出てきてしまった。つまり、lib ファイルがおかしいってことか・・・
mkexports.rb は使えない子?
lib ファイルを生成する元になる def ファイルを生成するのに mkexports.rb が使われているようだ。obj ファイルを入力すると、def の文字列を出力する仕組みらしい。
ruby_digitmap を定義している bignum.obj を食べさせてみると、
VERSION 1.9 EXPORTS ... ruby_digitmap DATA
ググってみると、ruby_digitmap = _ruby_digitmap とするべきらしいのだけど、ruby_digitmap だけになっている。どおりで通らないわけだ。恐らく他のも同じ調子なんだろう。仕方ないので、手動で def ファイルを生成して自動生成物と置き換え。
再度 gem に hpricot を食わせると、エラーもなくインストールが終わってくれた。
ビルドだけでも大変だったのに、こっちも気疲れするイベントだったとは。色々試してみたいのに・・・