2022/08/18(木) [n年前の日記]
#1 [ruby] exerbと格闘中
Ruby 1.8.7 p330 と Ruby/SDL (rubysdl) 1.3.1.1、2.1.1.1 を使って、Windows用のスクリーンセーバを作れないものかと実験しているところだけど、exe化するあたりでハマっているところ。
一応、ocra 1.3.1 を使って exe化はできたけど、ocra は動作に必要なファイルを一時ディレクトリに解凍して動く仕組みなので、予想はしていたけど結構起動が遅いわけで。そこでふと、exerb ならどうだろうと手を出してみたのだけど、これが上手く行かない…。
ちなみに、puts "Hello World" だけの Rubyスクリプトを exerb でexe化したら、ちゃんと動作する exe になった。Ruby の基本機能だけを使ったスクリプトならそこそこ動くということなのかな…。
実験環境は以下。
一応、ocra 1.3.1 を使って exe化はできたけど、ocra は動作に必要なファイルを一時ディレクトリに解凍して動く仕組みなので、予想はしていたけど結構起動が遅いわけで。そこでふと、exerb ならどうだろうと手を出してみたのだけど、これが上手く行かない…。
ちなみに、puts "Hello World" だけの Rubyスクリプトを exerb でexe化したら、ちゃんと動作する exe になった。Ruby の基本機能だけを使ったスクリプトならそこそこ動くということなのかな…。
実験環境は以下。
- Windows10 x64 21H2
- Ruby 1.8.7 p330 i386-mswin32 (ActiveScriptRuby) + rubysdl 2.1.1.1
- Ruby 1.8.7 p330 i386-mingw32 (RubyInstaller) + rubysdl 1.3.1.1
◎ 分かったこと。 :
- Ruby/SDL を使ったスクリプトを exerb で exe にする場合、.exy にSDL関連の .dll を追記してやる必要がある。
- rubysdl 2.1.1.1 は、どうやらdllのファイル名が長過ぎるようで、exerb ではexe化できなかった。
- rubysdl 1.3.1.1 は、dllファイル名の長さの問題は回避できそうだが、pngの読み込みができない exe になった。
- rubysdl 1.3.1.1 を利用して、かつ、画像は bmp のみに限定したら、動作する exe が生成された。
- しかし、exe を他のPCに持っていったら動かなかった…。
◎ 試行錯誤の記録。その1。 :
まず、Ruby 1.8.7 p330 mswin32 + rubysdl 2.1.1 の環境で、exerb 5.3.0 を使って exeファイルを作成してみた。
実行したところ、SDL関連のdllが読めないと言ってきた。
exerb にファイル構成等を指示するために、.exyファイルを作成してみる。
.exy内には、SDL関連dllが記述されてなかった。
ocra を使った時の出力結果を頼りにして、SDl関連dll を .exy に追記してみる。ちなみに、自分の環境では、Ruby 1.8.7 を C:/Ruby/Ruby187p330mswin32/ にインストールしてある。
.exy の一番最後(fileブロック内)に以下を追記。
exerb に .exy を指定してexeを生成。
しかし、出来上がった exeファイルを実行すると、以下のエラーが出る。
以下のスレッドが関係してそうだけど…。
_Re: exerb fails (exerb-eng:0059) - Exerb - OSDN
以下も関係あるだろうか。
_Exerb Project
何故かは分からないけど、exeファイル名は17文字までという制限があるらしい。一応、生成exeファイル名は17文字以下にしてみたのだけど、もしかして利用するdllファイル名も17文字以下でなければならないということだろうか。だとしたら、打つ手は無さそう…。
exerb rbsdlsav.rb.exe が生成された。
実行したところ、SDL関連のdllが読めないと言ってきた。
exerb にファイル構成等を指示するために、.exyファイルを作成してみる。
mkexy rbsdlsav.rb
.exy内には、SDL関連dllが記述されてなかった。
ocra を使った時の出力結果を頼りにして、SDl関連dll を .exy に追記してみる。ちなみに、自分の環境では、Ruby 1.8.7 を C:/Ruby/Ruby187p330mswin32/ にインストールしてある。
> ocra --version Ocra 1.3.1 > ocra --windows scrsavrubysdl.rb res === Loading script to check dependencies === Building scrsavrubysdl.exe === Adding user-supplied source files === Adding ruby executable rubyw.exe === Adding detected DLL C:/Ruby/Ruby187p330mswin32/bin/SDL_image.dll === Adding detected DLL C:/Ruby/Ruby187p330mswin32/bin/SDL.dll === Adding detected DLL C:/Ruby/Ruby187p330mswin32/bin/SDL_mixer.dll === Adding detected DLL C:/Ruby/Ruby187p330mswin32/bin/SGE.dll === Adding detected DLL C:/Ruby/Ruby187p330mswin32/bin/smpeg.dll === Adding detected DLL C:/Ruby/Ruby187p330mswin32/bin/SDL_ttf.dll === Adding detected DLL C:/Ruby/Ruby187p330mswin32/bin/libfreetype-6.dll === Adding detected DLL C:/Ruby/Ruby187p330mswin32/bin/zlib1.dll === Adding detected DLL C:/Ruby/Ruby187p330mswin32/bin/libpng12-0.dll === Adding library files === Compressing 3601505 bytes === Finished building scrsavrubysdl.exe (1187787 bytes)
.exy の一番最後(fileブロック内)に以下を追記。
sdl.so: file: C:/Ruby/Ruby187p330mswin32/lib/ruby/site_ruby/1.8/i386-msvcrt/sdl.so type: extension-library SDL_image.dll: file: C:/Ruby/Ruby187p330mswin32/bin/SDL_image.dll type: dynamic-library SDL.dll: file: C:/Ruby/Ruby187p330mswin32/bin/SDL.dll type: dynamic-library SDL_mixer.dll: file: C:/Ruby/Ruby187p330mswin32/bin/SDL_mixer.dll type: dynamic-library SGE.dll: file: C:/Ruby/Ruby187p330mswin32/bin/SGE.dll type: dynamic-library smpeg.dll: file: C:/Ruby/Ruby187p330mswin32/bin/smpeg.dll type: dynamic-library SDL_ttf.dll: file: C:/Ruby/Ruby187p330mswin32/bin/SDL_ttf.dll type: dynamic-library libfreetype-6.dll: file: C:/Ruby/Ruby187p330mswin32/bin/libfreetype-6.dll type: dynamic-library zlib1.dll: file: C:/Ruby/Ruby187p330mswin32/bin/zlib1.dll type: dynamic-library libpng12-0.dll: file: C:/Ruby/Ruby187p330mswin32/bin/libpng12-0.dll type: dynamic-library
exerb に .exy を指定してexeを生成。
exerb rbsdlsav.exy
しかし、出来上がった exeファイルを実行すると、以下のエラーが出る。
> rbsdlsav.exe sdl.rb:17:in `require': Couldn't modify DLL's name in the import table. The name of the executable file is too long. (LoadError) from sdl.rb:17
以下のスレッドが関係してそうだけど…。
_Re: exerb fails (exerb-eng:0059) - Exerb - OSDN
以下も関係あるだろうか。
_Exerb Project
> Q12. The error message "Fail to modify the import table. exe file name is too long." has appeared.
> A12. This message means that the exe file name must be written in 17 characters.
何故かは分からないけど、exeファイル名は17文字までという制限があるらしい。一応、生成exeファイル名は17文字以下にしてみたのだけど、もしかして利用するdllファイル名も17文字以下でなければならないということだろうか。だとしたら、打つ手は無さそう…。
◎ 試行錯誤の記録。その2。 :
Ruby/SDL (rubysdl) 2.1.1.1 を使っているスクリプトを、exerb を使って exe化するのは、ファイル名文字数の関係でどうやら難しい気配がしてきたわけだけど。
これが Ruby/SDL (rubysdl) 1.3.1 ならどうだろうか。rubysdl 1.3.1 なら、多少は dllファイル名が違っているはず。
Ruby 1.8.7 p330 i386-mingw32 + rubysdl 1.3.1 で試してみた。
ocra 1.3.1 の出力結果は以下。
.exy を作成。
生成された .exy を修正。
core を cui から gui に変更。
SDL関連dllの記述を追記。
exerb でexe化。
exeファイルが生成された。しかし、exe を実行すると、png関連のモジュールが見つからないと言ってきた。
Ruby/SDL でpng画像を利用しようとすると、このエラーに遭遇してしまうのだろう…。であればと、png画像を利用することを諦めて、bmp画像を使うことにしたら、上記のエラーが出てこなくなって、ようやく動作する exe が生成された。
と思ったがダメだった。他のPCに exe をコピーして実行すると例外が発生する。
exerb で変換作業をしたPC上なら動くが、他のPCでは動かないexeになってしまった。何故。
※ 2022/08/19追記。他のPCでexeを動かした際のエラーダイアログも載せておく。
試しに、Ruby 1.8.7 p330 i386-mswin32 (ActiveScriptRuby) + rubysdl 1.3.1 にしてexeに変換してみたけれど、症状変わらず。やはり他のPCにexeを持っていくとエラーが出る。mingw32版 Ruby ではなく、mswin32版 Ruby なら動いてくれるかと期待したけどダメだった。
exerb に渡した .exy は以下。
_rbsdlsav2.exy
これが Ruby/SDL (rubysdl) 1.3.1 ならどうだろうか。rubysdl 1.3.1 なら、多少は dllファイル名が違っているはず。
Ruby 1.8.7 p330 i386-mingw32 + rubysdl 1.3.1 で試してみた。
ocra 1.3.1 の出力結果は以下。
> ruby -v ruby 1.8.7 (2010-12-23 patchlevel 330) [i386-mingw32] > ruby -e "require 'sdl'; puts SDL::VERSION" 1.3.1 > ocra --version Ocra 1.3.1 > ocra --windows rbsdlsav.rb res === Loading script to check dependencies === Building rbsdlsav.exe === Adding user-supplied source files === Adding ruby executable rubyw.exe === Adding detected DLL C:/Ruby/Ruby187p330mingw32/bin/libiconv-2.dll === Adding detected DLL C:/Ruby/Ruby187p330mingw32/bin/SDL_mixer.dll === Adding detected DLL C:/Ruby/Ruby187p330mingw32/bin/SDL.dll === Adding detected DLL C:/Ruby/Ruby187p330mingw32/bin/SGE.dll === Adding detected DLL C:/Ruby/Ruby187p330mingw32/bin/SDL_image.dll === Adding detected DLL C:/Ruby/Ruby187p330mingw32/bin/SDL_ttf.dll === Adding detected DLL C:/Ruby/Ruby187p330mingw32/bin/smpeg.dll === Adding library files === Compressing 4309809 bytes === Finished building rbsdlsav.exe (1644661 bytes)
.exy を作成。
mkexy rbsdlsav2.rb
生成された .exy を修正。
core を cui から gui に変更。
core: gui
SDL関連dllの記述を追記。
zlib.so: file: C:/Ruby/Ruby187p330mingw32/lib/ruby/1.8/i386-mingw32/zlib.so type: extension-library SDL.dll: file: C:/Ruby/Ruby187p330mingw32/bin/SDL.dll type: dynamic-library SGE.dll: file: C:/Ruby/Ruby187p330mingw32/bin/SGE.dll type: dynamic-library SDL_mixer.dll: file: C:/Ruby/Ruby187p330mingw32/bin/SDL_mixer.dll type: dynamic-library SDL_image.dll: file: C:/Ruby/Ruby187p330mingw32/bin/SDL_image.dll type: dynamic-library SDL_ttf.dll: file: C:/Ruby/Ruby187p330mingw32/bin/SDL_ttf.dll type: dynamic-library smpeg.dll: file: C:/Ruby/Ruby187p330mingw32/bin/smpeg.dll type: dynamic-library zlib1.dll: file: C:/Ruby/Ruby187p330mingw32/bin/zlib1.dll type: dynamic-library libpng12.dll: file: C:/Ruby/Ruby187p330mingw32/bin/libpng12.dll type: dynamic-library libiconv-2.dll: file: C:/Ruby/Ruby187p330mingw32/bin/libiconv-2.dll type: dynamic-library libtiff.dll: file: C:/Ruby/Ruby187p330mingw32/bin/libtiff.dll type: dynamic-library jpeg.dll: file: C:/Ruby/Ruby187p330mingw32/bin/jpeg.dll type: dynamic-library libcharset-1.dll: file: C:/Ruby/Ruby187p330mingw32/bin/libcharset-1.dll type: dynamic-library ogg.dll: file: C:/Ruby/Ruby187p330mingw32/bin/ogg.dll type: dynamic-library vorbis.dll: file: C:/Ruby/Ruby187p330mingw32/bin/vorbis.dll type: dynamic-library vorbisfile.dll: file: C:/Ruby/Ruby187p330mingw32/bin/vorbisfile.dll type: dynamic-library
exerb でexe化。
exerb rbsdlsav2.exy
exeファイルが生成された。しかし、exe を実行すると、png関連のモジュールが見つからないと言ってきた。
> rbsdlsav2.exe rbsdlsav2.rb:197:in `loadFromIO': Couldn't load image from IO: Failed loading png_create_info_struct: 指定されたモジュールが見つかりません。 (SDL::Error) from rbsdlsav2.rb:197:in `get_surface_image_from_base64' from rbsdlsav2.rb:75:in `draw_fullscreen' from rbsdlsav2.rb:235
Ruby/SDL でpng画像を利用しようとすると、このエラーに遭遇してしまうのだろう…。であればと、png画像を利用することを諦めて、bmp画像を使うことにしたら、上記のエラーが出てこなくなって、ようやく動作する exe が生成された。
と思ったがダメだった。他のPCに exe をコピーして実行すると例外が発生する。
プログラムで例外が発生しました。詳細は下記の通りです。 タイプ: ExerbRuntime::Error メッセージ: Win32API Error #126 --- 指定されたモジュールが見つかりません。 バックトーレス: sdl.rb:17:in 'require' sdl.rb:17sdl.rb の 17行目には、require 'sdl.so' と書いてある。sdl.so を読み込むことができていないということだろうか…。
exerb で変換作業をしたPC上なら動くが、他のPCでは動かないexeになってしまった。何故。
※ 2022/08/19追記。他のPCでexeを動かした際のエラーダイアログも載せておく。
試しに、Ruby 1.8.7 p330 i386-mswin32 (ActiveScriptRuby) + rubysdl 1.3.1 にしてexeに変換してみたけれど、症状変わらず。やはり他のPCにexeを持っていくとエラーが出る。mingw32版 Ruby ではなく、mswin32版 Ruby なら動いてくれるかと期待したけどダメだった。
exerb に渡した .exy は以下。
_rbsdlsav2.exy
◎ 余談。exerb と DATA。 :
exerb で exe化した exe を動かしたところ、以下のエラーが出た。
スクリプトの最後につけた base64文字列を読み取れずにエラーを出している模様。
_DATAオブジェクトがきかない (exerb-dev:0477) - Exerb - OSDN
_Re: DATAオブジェクトがきかない(再送) (exerb-dev:0481) - Exerb - OSDN
_Re: DATAオブジェクトがきかない(再送) (exerb-dev:0485) - Exerb - OSDN
exerb は DATA云々に対応してなかったというオチらしい。
exerb はデータファイルを同梱させるのが難しそうなので、わざわざ画像ファイルのデータもスクリプト内に収めようと手を入れてみたのだけど、こんな罠があるとは…。
スクリプトの最後、__END__ 以下に記述していた base64文字列を、スクリプトの途中で配列定数として用意して利用するように書き換えたところ、一応動いてくれた。
> rbsdlsav.exe rbsdlsav.rb:150:in `get_surface_image_from_base64': uninitialized constant DATA (NameError) from rbsdlsav.rb:35:in `draw_fullscreen' from rbsdlsav.rb:192
スクリプトの最後につけた base64文字列を読み取れずにエラーを出している模様。
_DATAオブジェクトがきかない (exerb-dev:0477) - Exerb - OSDN
_Re: DATAオブジェクトがきかない(再送) (exerb-dev:0481) - Exerb - OSDN
_Re: DATAオブジェクトがきかない(再送) (exerb-dev:0485) - Exerb - OSDN
exerb は DATA云々に対応してなかったというオチらしい。
exerb はデータファイルを同梱させるのが難しそうなので、わざわざ画像ファイルのデータもスクリプト内に収めようと手を入れてみたのだけど、こんな罠があるとは…。
スクリプトの最後、__END__ 以下に記述していた base64文字列を、スクリプトの途中で配列定数として用意して利用するように書き換えたところ、一応動いてくれた。
[ ツッコむ ]
以上です。