Apache を動かすのは面倒すぎる。 HTTP サーバを同梱してしまうことにした。 と言っても Haskell で書くのはダルいので、 Ruby で WEBrick を使って書き、exerb でバイナリ化する作戦。
えーっと、インストールして、レシピファイル作って、exerb、で OK?
~/c/stdhaskell/src/lazylines % mkexr server.rb .... ^C ~/c/stdhaskell/src/lazylines % exerb server.exr ~/c/stdhaskell/src/lazylines % ./server.exe server.rb:3:in `require': No such file to load -- webrick (LoadError) from server.rb:3
ありゃ? なぜだろう。なぜかしら。
なんだか理由はよくわからないが、 Cygwin 版の Ruby を使ってるのがなんかまずいような気がしてきた。 これでは拡張ライブラリが使えないだろう。たぶん。 Windows 再インストール以来 VC++ でコンパイルしてないので、しよう。
nmake がネーヨ、とか (vcvars32.bat を実行するの忘れてた)、 bison がネーヨ、とか (Cygwin で実行してごまかす) 言われつつもコンパイル成功。
……しまったあああ! --prefix 付けるの忘れてた! コンパイルしなおしだ。
もいっかい exerb をやりなおす。
~/c/stdhaskell/src/lazylines % ruby-vc -rexerb/mkexr server.rb .... ^C ~/c/stdhaskell/src/lazylines % exerb-vc server.exr ~/c/stdhaskell/src/lazylines % ./server.exe server.rb:3:in `require': No such file to load -- webrick (LoadError) from server.rb:3
あれ? まだだめか。 もっと小さいスクリプトで試してみると、 require が入った瞬間にだめになるようだ。なぜだろう。
根拠なく、コアが何か違うのかなーとか疑ってみる。 とりあえず Ruby 1.9 コアを自分で作ってみるか。 えーと、VC++ で…… .dsp を開けばいいのかな。違った。.dsw のほうだ。
あー、プロジェクトが古いから鬼車が入ってないな。ファイルを登録する。
regex.c はいらないっと。 ファイルを削除するには……削除するには……あれ? 削除できないのかな。 とりあえず「このファイルはコンパイルしない」をチェックしておこう。
あああ、今度は exerb.cpp で大量のエラーが。 winsock2.h でエラーが腐るほど出ているなあ。なんだこれ。 俺の当てにならない勘によると、#include 順による問題と見たー。 ファイル冒頭の
#include <windows.h> #include <ruby.h>
を逆にしてみる。
通った。すげえな俺の勘。奇跡だ。 全ての *.cpp で ruby.h を先に #include するように変更。
今度はリンカでエラーが出るなあ。えーと、未解決シンボルが 58 個?
NtSyncProcess, SafeFree, Win32System, definekey, do_aspawn, do_spawn, mark_hash, mark_tbl, pipe_exec, rb_big_rand, rb_frame_last_func, rb_inspecting_p, rb_io_flags_mode, rb_obj_id_obsolete, rb_protect_inspect, rb_values_at, re_mbctab, re_set_syntax, ruby__end__seen, ruby_class, ruby_eval_tree_begin, ruby_in_compile, ruby_parser_stack_on_heap, ...
新しい Ruby に存在しないシンボルが全部しくじってるのかな。 どっかに古いシンボルテーブルが残ってると見た。
どっか、どころじゃない。 src/exerb/*.def を全部アップデートしなきゃいけないんだ。 これ、いかにも自動で作れそうなんだけど、なんかルールがないのかな。
む。Ruby 本体に msvcrt-ruby19.def というのがあるな。 これを使えばよいのか? とりあえず素直にコピィしてみる。
おお! 未解決シンボルが 6 個に減った! これは単にファイル追加忘れっぽいな。 enumerator.c, ascii.c, euc-jp.c, sjis.c を追加。
2 つに減った。えーと今度は __imp__WSASocketA@24 と __imp__WSAEnumProtocolsA@12 がないらしい。 WinSock のインポートライブラリをリンクしろってことかなあ。 Ruby 本体もリンクしてたっけ?
……なんかしてるなあ。 ws2_32.lib というのがそれっぽい。 これをリンクすればいいのだろうか。
えーと VC++ でリンクするライブラリを追加するには……。 [プロジェクト]→[プロジェクトへ追加]→[ファイル] で C:\Program Files\Microsoft Visual Studio\VC98\Lib\WS2_32.LIB を追加か。
なんとなく通ったようだ。
あれれれ? できたファイルはどこにあるのー!
わかった。project/ruby190c/debug の下だ。 よし! 作ったばっかりの新コアを使ってみるぜー!
~/c/stdhaskell/src/lazylines % mkexr server.rb .... ^C ~/c/stdhaskell/src/lazylines % exerb server.exr -C ruby190c.exc ~/c/stdhaskell/src/lazylines % ./server.exe server.rb:3:in `require': No such file to load -- webrick (LoadError) from server.rb:3
変わらねえ―――っ!
(次回に続く)
(05:24)
いま突然気付いたッ! 天啓が来ました。 もしかてもしなくても、 exerb の require は独自実装なんじゃないか? っていうか、そうじゃないとおかしいだろ > 俺
ということは、eval.c を単純に上書きしてしまったからダメなのに違いない。 それじゃ最初はどうして失敗したのかなーとかいう疑問もわいてくるんだけど、 このさい弱気になるのは禁止風味で行くことにしよう。
exerb の eval.c を調査。
VALUE rb_f_require(obj, fname) VALUE obj, fname; { return exerb_require(fname); }
やっぱりそうだ。require の中身が置き換わってる。 exerb-3.3.1/src/ruby-1.9.0/eval.c もこれと同じように書き換えてみる。
……まだだめだー。 やっぱりちゃんとした (?) バグなのか。 嫌だなあ。つくづく嫌だなあ。なんかめんどくさくなってきた。 Ruby のバイナリとかライブラリとか全部添付して済ませようかなあ。
しかし、何か変だな。ようするに、require を使ったときは、 exerb は最初っから最後まで動いてないわけだ。 いくらなんでもここまで変なら誰か気付くよなあ。 全然動かないってのは何か変だ。
あ……? わかつたー! たぶん $" に入るファイル名がフルパスになったからだ! そのせいで exerb_find_file_inside() がしくじってる。 ということは、もしかして、失敗するのは 1.9 限定?
やっぱり 1.8 は通るじゃん。うわーん。
(06:29)
exerb を使ったときだけ WEBrick の CGI が動かねえ。
な、な、なんで…… ruby を popen してんだよおおお―――――!
うう、そりゃそうだ。 fork がないんだから popen するしかないか。 うわぁーん。
おにょれ、ここであきらめてたまるか……。 今度は webrick/httpservlet/cgi_runner.rb を exerb で実行ファイル化、 あーんど、webrick/httpservlet/cgihandler.rb をベタ書き換えだー。
~/c/stdhaskell/src/lazylines % ./server.exe [2006-05-15 06:56:33] INFO WEBrick 1.3.1 [2006-05-15 06:56:33] INFO ruby 1.8.4 (2005-12-24) [i386-mswin32] [2006-05-15 06:56:33] DEBUG TCPServer.new(0.0.0.0, 10080) [2006-05-15 06:56:33] DEBUG WEBrick::HTTPServlet::FileHandler is mounted on /. [2006-05-15 06:56:33] INFO WEBrick::HTTPServer#start: pid=3100 port=10080 [2006-05-15 06:56:41] DEBUG accept: 127.0.0.1:1597 [2006-05-15 06:56:41] DEBUG WEBrick::HTTPServlet::FileHandler is invoked. nocturne - - [15/May/2006:06:56:41 ] "GET / HTTP/1.1" 200 929 [2006-05-15 06:56:41] DEBUG WEBrick::HTTPServlet::FileHandler is invoked. nocturne - - [15/May/2006:06:56:41 ] "GET /default.css HTTP/1.1" 304 0 [2006-05-15 06:56:49] DEBUG WEBrick::HTTPServlet::FileHandler is invoked. nocturne - - [15/May/2006:06:56:49 ] "GET /?cmd=view;name=LazyLines HTTP/1.1" 200 930 [2006-05-15 06:56:57] DEBUG WEBrick::HTTPServlet::FileHandler is invoked. nocturne - - [15/May/2006:06:56:57 ] "GET /?cmd=view;name=WikiClone HTTP/1.1" 200 842 [2006-05-15 06:57:02] DEBUG WEBrick::HTTPServlet::FileHandler is invoked. nocturne - - [15/May/2006:06:57:02 ] "GET /?cmd=view;name=LazyLinesSyntax HTTP/1.1" 200 2507
よっしゃ動いたー! 完・全・勝・利!
(06:56)
しまったああああ! Linux より Windows のほうがインストールが楽になってしまった…… orz Linux ではバイナリは通用しないし、結局 Apache の設定を説明しなきゃいけないのか。 うざー。
なーんか面倒だし、ruby をインストールしてもらうことにしようかなあ。 それとも gcc は当然入ってるよねっ、 ということにして C でウェブサーバを書く (ふつりな再利用) か。 それすらも面倒だから Ruby のソースコードを まるごと入れといてコンパイル……とか……だめっすかね……。だめですね……。
(08:09)
せっかく作ったので Windows 用 LazyLines バイナリ (+ HTTP サーバ) にリンク張っとく。
使いかた……ダウンロードして、解凍して、server.exe をダブルクリック。 同じホストのウェブブラウザから http://localhost:10081 にアクセス。終
(08:34)
スタティックリンクした ruby を添付、という手はあるな。
sh で書いてある HTTP サーバを探す、とか (しかし改造するのがダルいなー)。
あとは…… C で書いた HTTP サーバをスタティックリンクする? なんかこれが一番楽そうな気がしてきたぞ。
続きは帰宅後。
(09:27)
Copyright (c) 2002-2007 青木峰郎 / Minero Aoki. All rights reserved.