2018/03/12(月) [n年前の日記]
#2 [ruby][mruby] MinGWでSDL2関係のビルドができるか実験
Windows10 x64 上で、mruby-sdl2 をビルドしたい。が、どうも sdl2-config を呼び出してるように見える。
_crimsonwoods/mruby-sdl2: mrbgem to use SDL2.0
_mruby-sdl2/mrbgem.rake at master - crimsonwoods/mruby-sdl2
sdl2-config の中身はシェルスクリプトなので、bash だの sh だのが用意されてる環境が前提のような気がする。となると、Visual Studio (Visual C++) を使ったビルドはできない予感。
しかし、もしかしたら MinGW + MSYS ならビルドできるのだろうか…? 実験してみないと分からんな…。実験しよう…。
_crimsonwoods/mruby-sdl2: mrbgem to use SDL2.0
_mruby-sdl2/mrbgem.rake at master - crimsonwoods/mruby-sdl2
sdl2-config の中身はシェルスクリプトなので、bash だの sh だのが用意されてる環境が前提のような気がする。となると、Visual Studio (Visual C++) を使ったビルドはできない予感。
しかし、もしかしたら MinGW + MSYS ならビルドできるのだろうか…? 実験してみないと分からんな…。実験しよう…。
◎ SDL2関係のインストール。 :
以下の記事を参考にして、MinGW + MSYS で、SDL2関係が使えるように環境を整える。
_MinGW 用の SDL2 インストール手順 メモ
_MinGW (32bit) 開発環境 インストール手順 メモ
自分の環境には MinGW + MSYS がインストールしてあるので、足りてなかった mingw32-libz dev (v1.2.8-1) だけ、MinGW Installer を使って、追加インストールした。
環境変数PATHの最初のほうに、以下を追加した状態で…。つまり、MinGW の bin/* と、MSYS の bin/* が呼び出せるようにしておいてから…。
C:\mingw\MinGW\msys\1.0\msys.bat を実行。bash が起動する。
MinGW 用の SDL2関係ファイルを入手。
_Simple DirectMedia Layer - SDL version 2.0.8 (stable)
_https://www.libsdl.org/release/SDL2-devel-2.0.8-mingw.tar.gz
SDL2-devel-2.0.8-mingw.tar.gz をDL・解凍して、出てきたディレクトリをカレントディレクトリにする。今回は、D:\sdl2\dev\mingw\ というフォルダを作成して、その中に入れておいた。
以下を実行。
これで、MinGWインストールフォルダ内の bin/ , include/ , lib/ ディレクトリ等の中に、SDL2関係のファイル(*.dll , *.h , *.a 等)がコピーされた。ちなみに、sdl2-config も bin/ にコピーされて、実行権限もついている。
この make install-package、今まで知らなかった…。これでサクッと下準備ができたのか…。
_MinGW 用の SDL2 インストール手順 メモ
_MinGW (32bit) 開発環境 インストール手順 メモ
自分の環境には MinGW + MSYS がインストールしてあるので、足りてなかった mingw32-libz dev (v1.2.8-1) だけ、MinGW Installer を使って、追加インストールした。
環境変数PATHの最初のほうに、以下を追加した状態で…。つまり、MinGW の bin/* と、MSYS の bin/* が呼び出せるようにしておいてから…。
C:\mingw\MinGW\bin;C:\mingw\MinGW\msys\1.0\bin
C:\mingw\MinGW\msys\1.0\msys.bat を実行。bash が起動する。
MinGW 用の SDL2関係ファイルを入手。
_Simple DirectMedia Layer - SDL version 2.0.8 (stable)
_https://www.libsdl.org/release/SDL2-devel-2.0.8-mingw.tar.gz
SDL2-devel-2.0.8-mingw.tar.gz をDL・解凍して、出てきたディレクトリをカレントディレクトリにする。今回は、D:\sdl2\dev\mingw\ というフォルダを作成して、その中に入れておいた。
以下を実行。
make install-package arch=i686-w64-mingw32 prefix=/mingw
これで、MinGWインストールフォルダ内の bin/ , include/ , lib/ ディレクトリ等の中に、SDL2関係のファイル(*.dll , *.h , *.a 等)がコピーされた。ちなみに、sdl2-config も bin/ にコピーされて、実行権限もついている。
この make install-package、今まで知らなかった…。これでサクッと下準備ができたのか…。
◎ ビルドしてみる。 :
以下を参考にして、サンプルがビルドできるかどうか確認。
_MSYS2 + MinGW 環境に SDL2 をインストール - takaya030の備忘録
適当なフォルダを作成して、sdl2_sample.cpp を作成。sdl2_sample.cpp の内容は、上記ページのソレを使わせてもらったり。ちなみに、return (TRUE); でエラーが出たので、return (true); に変更。
Makefile を作成。上記ページのソレを参考にして、内容は以下にした。SDL_PREFIX を /mingw にしてるところが違い、だろうか。
make を実行。sdl2_sample.o と sdl2_sample.exe ができた。
sdl2_sample.exe を実行。ウインドウが開いて何か描画された。
とりあえずここまでの作業で、MinGW + MSYS を利用すれば SDL2 を使った何かしらをビルドすることはできる、と分かった。
_MSYS2 + MinGW 環境に SDL2 をインストール - takaya030の備忘録
適当なフォルダを作成して、sdl2_sample.cpp を作成。sdl2_sample.cpp の内容は、上記ページのソレを使わせてもらったり。ちなみに、return (TRUE); でエラーが出たので、return (true); に変更。
Makefile を作成。上記ページのソレを参考にして、内容は以下にした。SDL_PREFIX を /mingw にしてるところが違い、だろうか。
TARGETS = sdl2_sample all: $(TARGETS) SDL_PREFIX = /mingw SDL_CONFIG = $(SDL_PREFIX)/bin/sdl2-config CG_LIBS = CROSS_COMPILE = /mingw/bin/ CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ CFLAGS = -g -Wall `/bin/sh $(SDL_CONFIG) --cflags` CXXFLAGS = -g -Wall `/bin/sh $(SDL_CONFIG) --cflags` LDFLAGS = `/bin/sh $(SDL_CONFIG) --libs` -Wl,-rpath,$(SDL_PREFIX)/lib LIBS = -lopengl32 -lglu32 -lm clean: rm -f *.o *.a *~ $(TARGETS) sdl2_sample: sdl2_sample.o $(CXX) -o $@ $^ $(LDFLAGS) $(LIBS)clean: だの sdl2_sample: だのの次の行の先頭のスペースは、タブ文字を入れておかないといかんらしい。空白スペース4つにしたら、「区切り文字がおかしいぞ」と怒られた。
make を実行。sdl2_sample.o と sdl2_sample.exe ができた。
sdl2_sample.exe を実行。ウインドウが開いて何か描画された。
とりあえずここまでの作業で、MinGW + MSYS を利用すれば SDL2 を使った何かしらをビルドすることはできる、と分かった。
◎ mruby-sdl2 をビルドしようとするが失敗。 :
以下の mrbgem をビルドできるのか実験。
_crimsonwoods/mruby-sdl2: mrbgem to use SDL2.0
mruby のファイル一式が入ってるディレクトリをカレントディレクトリにして、build_config.rb を編集。以下を最初のほうに追加。
make を実行。エラーが出た。
sdl2-config が無いと言われてるような気がする…。でも、変だな。sdl2-config は、PATHが通った場所に、ちゃんとあるように見えるけど。
_crimsonwoods/mruby-sdl2: mrbgem to use SDL2.0
mruby のファイル一式が入ってるディレクトリをカレントディレクトリにして、build_config.rb を編集。以下を最初のほうに追加。
conf.gem :github => 'crimsonwoods/mruby-sdl2', :branch => 'master'
make を実行。エラーが出た。
$ make ruby ./minirake (in d:/Ruby/mruby/mruby) CC build/mrbgems/mruby-sdl2/src/misc.c -> build/host/mrbgems/mruby-sdl2/src/misc.o gcc: error: `sdl2-config: No such file or directory gcc: error: unrecognized command line option '--cflags`' gcc: error: `sdl2-config: No such file or directory gcc: error: unrecognized command line option '--cflags`' rake aborted! Command Failed: [gcc -g -std=gnu99 -O3 -Wall -Werror-implicit-function-declaration -Wdeclaration-after-statement -Wwrite-strings -g3 -O0 `sdl2-config --cflags` -DMRB_DEBUG -DMRBGEM_MRUBY_SDL2_VERSION=0.0.0 -I"d:/Ruby/mruby/mruby/include" -MMD -o "d:/Ruby/mruby/mruby/build/host/mrbgems/mruby-sdl2/src/misc.o" -c "d:/Ruby/mruby/mruby/build/mrbgems/mruby-sdl2/src/misc.c"] make: *** [all] Error 1
sdl2-config が無いと言われてるような気がする…。でも、変だな。sdl2-config は、PATHが通った場所に、ちゃんとあるように見えるけど。
$ which sdl2-config /mingw/bin/sdl2-configあるよなあ。おかしいな。
◎ Windowsの場合はshebangが使えないのではないかという疑惑。 :
*NIXの世界では、shebang というものがあって。
_シバン (Unix) - Wikipedia
テキストファイルの一行目に、
「このテキストファイルは /bin/sh で動かすファイルだよ」
「このテキストファイルは /usr/bin/env ruby で見つかったファイルで動かすファイルだよ」
という指定になって、それぞれを動かすことができる ―― てな仕組みを shebang と呼ぶらしい。
sdl2-config も、一番最初の行に、
しかし、Windows上で動く Ruby は、shebang は見てないような気がするわけで。
MinGW + MSYS 上で、Ruby mingw版 の irb を実行すると…。
ならば、mruby-sdl2 の、mrbgem.rake を修正して、sdl2-config の前に sh をつければ動くのだろうか。以下のように修正してみた。
sdl2-config のみならず、sh すら見つからないと言ってきた。うーん。
もしかして、rake だか minirake だか分からんけど、どうもソレが動いてるときは、MinGW の bin/ や MSYS の bin/ を検索できないPATH状態になっているのかな…。
_シバン (Unix) - Wikipedia
テキストファイルの一行目に、
#!/bin/shとか
#!/usr/bin/ebv rubyと書いておくと、
「このテキストファイルは /bin/sh で動かすファイルだよ」
「このテキストファイルは /usr/bin/env ruby で見つかったファイルで動かすファイルだよ」
という指定になって、それぞれを動かすことができる ―― てな仕組みを shebang と呼ぶらしい。
sdl2-config も、一番最初の行に、
#!/bin/shと書いてある。だから、bash上で、いきなり sdl2-config と打っても、実行することができる。
しかし、Windows上で動く Ruby は、shebang は見てないような気がするわけで。
mieki256@hogefuga: MINGW32: ~$ ruby -v ruby 2.2.6p396 (2016-11-15 revision 56800) [i386-mingw32] mieki256@hogefuga: MINGW32: ~$ irb irb(main):001:0> `echo "hoge"` => "\"hoge\"\n" irb(main):002:0> `which sdl2-config` => "\"C:\\mingw\\MinGW\\bin\\sdl2-config\"\n" irb(main):003:0> `sdl2-config` Errno::ENOENT: No such file or directory - sdl2-config from (irb):3:in ``' from (irb):3 from c:/Ruby/Ruby22/bin/irb:11:in `<main>' irb(main):004:0> `sh sdl2-config` Usage: sdl2-config [--prefix[=DIR]] [--exec-prefix[=DIR]] [--version] [--cflags] [--libs] [--static-libs] => "" irb(main):005:0> exit
MinGW + MSYS 上で、Ruby mingw版 の irb を実行すると…。
- `which sdl2-config` で、sdl2-config が置いてある場所を把握できていることは分かる。
- しかし、`sdl2-config` をしても、実行できない。
- `sh sdl2-config` なら、実行できる。
ならば、mruby-sdl2 の、mrbgem.rake を修正して、sdl2-config の前に sh をつければ動くのだろうか。以下のように修正してみた。
MRuby::Gem::Specification.new('mruby-sdl2') do |spec| spec.license = 'MIT' spec.authors = 'crimsonwoods' spec.cc.flags << '`sh sdl2-config --cflags`' spec.linker.flags_before_libraries << '`sh sdl2-config --libs`' end
mieki256@dorobune: MINGW32: /d/Ruby/mruby/mruby$ make ruby ./minirake (in d:/Ruby/mruby/mruby) CC build/mrbgems/mruby-sdl2/src/misc.c -> build/host/mrbgems/mruby-sdl2/src/misc.o gcc: error: `sh: No such file or directory gcc: error: sdl2-config: No such file or directory gcc: error: unrecognized command line option '--cflags`' gcc: error: `sh: No such file or directory gcc: error: sdl2-config: No such file or directory gcc: error: unrecognized command line option '--cflags`' rake aborted! Command Failed: [gcc -g -std=gnu99 -O3 -Wall -Werror-implicit-function-declaration -Wdeclaration-after-statement -Wwrite-strings -g3 -O0 `sh sdl2-config --cflags` -DMRB_DEBUG -DMRBGEM_MRUBY_SDL2_VERSION=0.0.0 -I"d:/Ruby/mruby/mruby/include" -MMD -o "d:/Ruby/mruby/mruby/build/host/mrbgems/mruby-sdl2/src/misc.o" -c "d:/Ruby/mruby/mruby/build/mrbgems/mruby-sdl2/src/misc.c"] make: *** [all] Error 1
sdl2-config のみならず、sh すら見つからないと言ってきた。うーん。
もしかして、rake だか minirake だか分からんけど、どうもソレが動いてるときは、MinGW の bin/ や MSYS の bin/ を検索できないPATH状態になっているのかな…。
◎ 直接書いてみる。 :
このあたり、要するに、sdl2-config が出力した文字列を、コンパイラだかリンカだかのオプションとして指定してる、ということだよなと。
だったら、sdl2-config を介さずに、sdl2-config が出力した文字列を、mrbgem.rake に直接書いちゃえば、ひとまずビルドが通ったりしないかと思えてきたわけで。
上の出力結果を参考にして、mrbgem.rake を以下のように修正。
これで make したら…。
ググってみたら、mrb_ary_len は、 _mruby 1.3.0 まではあった けど、 _mruby 1.4.0 では無くなった ように見える。
ということは、mrb_ary_len() を別の何かで代替すればビルドできるようになるのかな。と思ってググってみたけど、「代わりにコレを使えや」という話は見つからず。そもそもどうして無くなったんだろう…。神様の気分かな。
ならば、mruby 1.3.0 のファイル一式を使えばビルドできるんじゃないか。 _Releases - mruby/mruby から 1.3.0 のzip をDL・解凍して、それらのファイル群を使って試してみた。
今度は「strlen なんて知らねえよ」とエラーが出た。
おかしいな…。mruby のソースの中でも strlen() って結構使われてるのに…。
mruby-sdl2 の sdl2.h に #include <string.h> を追加してみた。一応ビルドは通ったように見えた。
ビルドは通ったけど、実行してもうんともすんとも言わない mruby.exe や mirb.exe が出来上がってしまった…。なんだこりゃ…。
mruby-sdl2 を追加すると、文字の出力ができない mruby, mirb が出来上がるっぽいな…。外してビルドすると各種メッセージがちゃんと表示される…。何故。
だったら、sdl2-config を介さずに、sdl2-config が出力した文字列を、mrbgem.rake に直接書いちゃえば、ひとまずビルドが通ったりしないかと思えてきたわけで。
$ sdl2-config --cflags -I/mingw/include/SDL2 -Dmain=SDL_main $ sdl2-config --libs -L/mingw/lib -lmingw32 -lSDL2main -lSDL2 -mwindows
上の出力結果を参考にして、mrbgem.rake を以下のように修正。
MRuby::Gem::Specification.new('mruby-sdl2') do |spec| spec.license = 'MIT' spec.authors = 'crimsonwoods' # spec.cc.flags << '`sh sdl2-config --cflags`' # spec.linker.flags_before_libraries << '`sh sdl2-config --libs`' spec.cc.flags << '-I"d:/mingw/MinGW/include/SDL2" -Dmain=SDL_main' spec.linker.flags_before_libraries << '-L"d:/mingw/MinGW/lib" -lmingw32 -lSDL2main -lSDL2 -mwindows' end
これで make したら…。
mieki256@dorobune: MINGW32: /d/Ruby/mruby/mruby$ make ruby ./minirake (in d:/Ruby/mruby/mruby) CC build/mrbgems/mruby-sdl2/src/misc.c -> build/host/mrbgems/mruby-sdl2/src/misc.o d:/Ruby/mruby/mruby/build/mrbgems/mruby-sdl2/src/misc.c: In function 'mrb_sdl2_misc_buffer_initialize': d:/Ruby/mruby/mruby/build/mrbgems/mruby-sdl2/src/misc.c:37:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] mrb_sdl2_misc_buffer_data_t *data = ^~~~~~~~~~~~~~~~~~~~~~~~~~今までと違って、sdl2-config が見つからない等の文句は出なくなった。しかし、それでもエラーが。「mrb_ary_len なんて知らんわい」と怒られてる。
d:/Ruby/mruby/mruby/build/mrbgems/mruby-sdl2/src/misc.c:49:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] enum mrb_vtype const arg_type = mrb_type(arg); ^~~
d:/Ruby/mruby/mruby/build/mrbgems/mruby-sdl2/src/misc.c:62:25: error: implicit declaration of function 'mrb_ary_len' [-Werror=implicit-function-declaration] mrb_int const n = mrb_ary_len(mrb, arg); ^~~~~~~~~~
... d:/Ruby/mruby/mruby/build/mrbgems/mruby-sdl2/src/misc.c:446:3: warning: ISO C90 forbids mixed declarations and code [-Wdeclaration-after-statement] mrb_sdl2_misc_buffer_data_t *data = ^~~~~~~~~~~~~~~~~~~~~~~~~~
cc1.exe: some warnings being treated as errors rake aborted! Command Failed: [gcc -g -std=gnu99 -O3 -Wall -Werror-implicit-function-declaration -Wdeclaration-after-statement -Wwrite-strings -g3 -O0 -I"d:/mingw/MinGW/include/SDL2" -Dmain=SDL_main -DMRB_DEBUG -DMRBGEM_MRUBY_SDL2_VERSION=0.0.0 -I"d:/Ruby/mruby/mruby/include" -MMD -o "d:/Ruby/mruby/mruby/build/host/mrbgems/mruby-sdl2/src/misc.o" -c "d:/Ruby/mruby/mruby/build/mrbgems/mruby-sdl2/src/misc.c"] make: *** [all] Error 1
ググってみたら、mrb_ary_len は、 _mruby 1.3.0 まではあった けど、 _mruby 1.4.0 では無くなった ように見える。
ということは、mrb_ary_len() を別の何かで代替すればビルドできるようになるのかな。と思ってググってみたけど、「代わりにコレを使えや」という話は見つからず。そもそもどうして無くなったんだろう…。神様の気分かな。
ならば、mruby 1.3.0 のファイル一式を使えばビルドできるんじゃないか。 _Releases - mruby/mruby から 1.3.0 のzip をDL・解凍して、それらのファイル群を使って試してみた。
今度は「strlen なんて知らねえよ」とエラーが出た。
おかしいな…。mruby のソースの中でも strlen() って結構使われてるのに…。
mruby-sdl2 の sdl2.h に #include <string.h> を追加してみた。一応ビルドは通ったように見えた。
ビルドは通ったけど、実行してもうんともすんとも言わない mruby.exe や mirb.exe が出来上がってしまった…。なんだこりゃ…。
mruby-sdl2 を追加すると、文字の出力ができない mruby, mirb が出来上がるっぽいな…。外してビルドすると各種メッセージがちゃんと表示される…。何故。
◎ 余談。 :
mruby関係の記事をググって眺めていた際、「mruby のライブラリ作者は mruby 本体のアップデートに追従していくのが大変」という話を見かけたけれど。なるほど、こんな感じで、今までビルドできていたものがビルドできなくなっていくのかと、たかだか一例ではあるけれど、素人なりになんとなく分かったつもりになったりもして。
また、Ruby関係は、「タダ乗りさせないために積極的に改変していく」「タダ乗り連中は置いてけぼりにする」というポリシーで開発をしていると神様自ら発言しているわけで…。
_今日現在のmrubyについて雑想 - もなもなもなかのページ
_参加しないと見せないよ.を作った罪 - もなもなもなかのページ
「コレどうしてビルドできないんだ」と仮に問うてみても、「俺達についてこないライブラリ作者が悪い」と返されるのがRubyの文化、なのだろうと。
mruby + SDL2 で、love2d みたいな形でアプリを作っておけば、CRuby のバージョンが上がるたびにライブラリ側も更新する苦労を味合わなくて済むのだろうか、などと素人考えで夢想していたのだけど。mruby も mruby で、コレを使うのはなんだか大変そうだなという印象になってきたりもして。だったら、まだ、古い CRuby + ライブラリで作業してたほうがいいのかもしれないよな…。
いやまあ、love2d みたいなのが欲しければ love2d 使えばいいじゃん、lua も比較的習得しやすい言語だし、という話にもなりそうだけど。
また、Ruby関係は、「タダ乗りさせないために積極的に改変していく」「タダ乗り連中は置いてけぼりにする」というポリシーで開発をしていると神様自ら発言しているわけで…。
_今日現在のmrubyについて雑想 - もなもなもなかのページ
_参加しないと見せないよ.を作った罪 - もなもなもなかのページ
「コレどうしてビルドできないんだ」と仮に問うてみても、「俺達についてこないライブラリ作者が悪い」と返されるのがRubyの文化、なのだろうと。
mruby + SDL2 で、love2d みたいな形でアプリを作っておけば、CRuby のバージョンが上がるたびにライブラリ側も更新する苦労を味合わなくて済むのだろうか、などと素人考えで夢想していたのだけど。mruby も mruby で、コレを使うのはなんだか大変そうだなという印象になってきたりもして。だったら、まだ、古い CRuby + ライブラリで作業してたほうがいいのかもしれないよな…。
いやまあ、love2d みたいなのが欲しければ love2d 使えばいいじゃん、lua も比較的習得しやすい言語だし、という話にもなりそうだけど。
[ ツッコむ ]
以上です。