iconvを使ったRubyスクリプトをExerbでexe化し実行すると、"`require': No such file to load -- iconv"と言われた

json_pureを使ったスクリプトをexe化するとiconvを使用している箇所でエラーが発生する現象が起きたので調査してみた。

以下のようなRubyスクリプトをexe化してみる。(ファイル名は"text.rb"とする)

require 'iconv'
UTF16toUTF8 = Iconv.new('utf-16be', 'utf-8')
p UTF16toUTF8.iconv('no bom')

まずmkexyを実行してレシピファイルを作る。
するとtest.exyという名前で以下のようなレシピファイルができる。

# Generated by mkexy
# on 2010-01-29 00:22

general:
  startup: test.rb
  core: cui
  kcode: none

file:
  test.rb:
  iconv.so:
    file: C:/PROGRA~1/ruby-1.8/lib/ruby/1.8/i386-mswin32/iconv.so
    type: extension-library

これで、exerb test.exyを実行し、exeファイルを生成し実行してみる。
すると、以下のようなエラーが発生する。

test.rb:1:in `require': Win32API Error #126 --- 指定されたモジュールが見つかりません。
 (ExerbRuntime::Error)
        from test.rb:1

で、なんとなくiconv.dllをレシピファイルに追加してみる。

# Generated by mkexy
# on 2010-01-29 00:22

general:
  startup: test.rb
  core: cui
  kcode: none

file:
  test.rb:
  iconv.so:
    file: C:/PROGRA~1/ruby-1.8/lib/ruby/1.8/i386-mswin32/iconv.so
    type: extension-library
  iconv.dll:
    file: C:/PROGRA~1/ruby-1.8/bin/iconv.dll

すると、すこし状況が進展したと思われ、以下のようにエラー内容がかわった。

test.rb:1:in `require': No such file to load -- iconv (LoadError)
        from test.rb:1

ここでイロイロ調べたが、解決方法がよくわからず行き詰まった。

とりあえずの回避方法

いろいろコードをいじっているうちに偶然みつけた。
iconvを require するところを、require 'iconv.so'のように拡張子付きにしてあげるとエラーが出なくなった。
最終的にうまく言ったコードは以下のようになった。

require 'iconv.so'
UTF16toUTF8 = Iconv.new('utf-16be', 'utf-8')
p UTF16toUTF8.iconv('no bom')

うーん、理由がよくわからない。
MLに投げてみようか?