mieki256's diary



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 の基本機能だけを使ったスクリプトならそこそこ動くということなのかな…。

実験環境は以下。

分かったこと。 :

  • 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ファイルを作成してみた。
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 の出力結果は以下。
> 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:17
sdl.rb の 17行目には、require 'sdl.so' と書いてある。sdl.so を読み込むことができていないということだろうか…。

exerb で変換作業をしたPC上なら動くが、他のPCでは動かないexeになってしまった。何故。

※ 2022/08/19追記。他のPCでexeを動かした際のエラーダイアログも載せておく。

ss_exerb_error.png

試しに、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 を動かしたところ、以下のエラーが出た。
> 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文字列を、スクリプトの途中で配列定数として用意して利用するように書き換えたところ、一応動いてくれた。

以上、1 日分です。

過去ログ表示

Prev - 2022/08 - Next
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30 31

カテゴリで表示

検索機能は Namazu for hns で提供されています。(詳細指定/ヘルプ


注意: 現在使用の日記自動生成システムは Version 2.19.6 です。
公開されている日記自動生成システムは Version 2.19.5 です。

Powered by hns-2.19.6, HyperNikkiSystem Project