2014/12/27(土) [n年前の日記]
#1 [dxruby][ruby] ayame.soをビルドしようとしてハマり中
環境は、Windows7 x64 + RubyInstaller 1.9.3 x86(mingw版) + DevKit(MinGW/MSYS)。
ayame.so 0.0.3 のソースファイル群の中に extconf.rb があるので、まずはソレを使って Makefile を作ろうと試みる。
make を実行。
dsound.h は、おそらく DirectX SDK のインストール場所/Include に入ってる予感。ヘッダファイル(.h)の他に、ライブラリファイル(.lib)も必要になるのかな。以下に入ってそう。
extconf.rb の中で実際に仕事をしてくれているのは、mkmf というモジュールらしい。 _library mkmf を眺めたら、--with-opt-include=DIR、--with-opt-lib=DIR を指定することで、ヘッダファイルとライブラリファイルの場所を教えてやることができる、と書いてあった。試してみる。
sal.h はどこにあるんだろう。たぶん、Visual C++ のインストール場所かな。
でも、どうやって複数の場所を指定すればいいんだろう…? extconf.rb の使用例をググってみたけど、コマンドラインオプションで指定する方法は見つからない。
とりあえず、Makefile を直接書き換えてみた。
make したら大量のエラーと警告が。ダメだあ〜(Undercover Cops のノリで)。
さて、そうなると…。
ayame.so 0.0.3 のソースファイル群の中に extconf.rb があるので、まずはソレを使って Makefile を作ろうと試みる。
> c:\DevKitインストール場所\devkitvars.bat > ruby extconf.rb checking for main() in -ldsound... yes checking for main() in -lole32... yes creating MakefileMakefile ができたように見えた。
make を実行。
> make generating ayame-i386-mingw32.def compiling ayame_ruby.cpp cc1plus.exe: warning: command line option "-Wdeclaration-after-statement" is valid for C/ObjC but not for C++ cc1plus.exe: warning: command line option "-Wimplicit-function-declaration" is valid for C/ObjC but not for C++ In file included from AyameManager.h:13:0, from VoiceElementAyame.h:10, from ayame_ruby.cpp:11: Ayame.h:12:20: fatal error: dsound.h: No such file or directory compilation terminated. make: *** [ayame_ruby.o] Error 1「dsound.h なんて無いよ」と怒られる。
dsound.h は、おそらく DirectX SDK のインストール場所/Include に入ってる予感。ヘッダファイル(.h)の他に、ライブラリファイル(.lib)も必要になるのかな。以下に入ってそう。
C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/Include C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/Libこの2つの場所をどこかで指定してやらないといけない気がする。
extconf.rb の中で実際に仕事をしてくれているのは、mkmf というモジュールらしい。 _library mkmf を眺めたら、--with-opt-include=DIR、--with-opt-lib=DIR を指定することで、ヘッダファイルとライブラリファイルの場所を教えてやることができる、と書いてあった。試してみる。
> ruby extconf.rb --with-opt-include="C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/Include" --with-opt-lib="C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/Lib" checking for main() in -ldsound... yes checking for main() in -lole32... yes creating Makefile
> make compiling ayame_ruby.cpp cc1plus.exe: warning: command line option "-Wdeclaration-after-statement" is valid for C/ObjC but not for C++ cc1plus.exe: warning: command line option "-Wimplicit-function-declaration" is valid for C/ObjC but not for C++ In file included from Ayame.h:12:0, from AyameManager.h:13, from VoiceElementAyame.h:10, from ayame_ruby.cpp:11: C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/Include/dsound.h:13:17: fatal error: sal.h: No such file or directory compilation terminated. make: *** [ayame_ruby.o] Error 1今度は「sal.h が無いよ」と怒られた。dsound.h の中で #include <sal.h> と書かれてるようだけど…。
sal.h はどこにあるんだろう。たぶん、Visual C++ のインストール場所かな。
C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/include C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/libこの2つをさらに指定すればいいのかな?
でも、どうやって複数の場所を指定すればいいんだろう…? extconf.rb の使用例をググってみたけど、コマンドラインオプションで指定する方法は見つからない。
とりあえず、Makefile を直接書き換えてみた。
CPPFLAGS = "-IC:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/include" "-IC:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/include" -DFD_SETSIZE=2048 $(DEFS) $(cppflags)
LIBPATH = -L. -L$(libdir) -L"C:/Program Files (x86)/Microsoft DirectX SDK (June 2010)/lib" -L"C:/Program Files (x86)/Microsoft Visual Studio 9.0/VC/lib"
make したら大量のエラーと警告が。ダメだあ〜(Undercover Cops のノリで)。
◎ もう少し分かってきた。 :
- DirectX SDK、Visual C++ の、ヘッダファイル・ライブラリファイルは、MinGW と互換性が無い。Visual C++ 用のライブラリファイルは、拡張子が *.lib。MinGW 用のライブラリファイルは、拡張子が *.a。だから、上の方でやってた作業は頓珍漢。
- 実は MinGW の中に、DirectX用のヘッダファイルが含まれてる。d3d9.h がソレ。DirectX9相当らしい。
- しかし、MinGW の中に、dsound.h は無い。
- ところが、MinGW 用ライブラリファイルの中に、libdsound.a はある。どゆこと?
さて、そうなると…。
- ayame.so を、Visual C++ でコンパイル・ビルドする手順を探すか。しかし、MinGW版 Ruby で使える拡張ライブラリを作るには、Visual C++ 6.0 が必要だったような?
- それとも、MinGW で dsound.h を使ったソースもコンパイルできる環境を整えるか。
◎ dsound.hの使い方が解説されてた。 :
このタイミングで、
_DirectSoundとRubyのプログラミング - mirichiの日記
という記事を公開していただけた! ありがたや。感謝なのです。
どうやら MinGW64なら、dsound.h を使ったソースもビルドできるらしい…。そのあたりから辿って、おかげで色々分かってきたり。
ということで、pik で Ruby 2.0.0 に切り替えて、2.0.0用の devkitvars.bat でPATHを変更して、ruby extconf.rb や make をしてみた。
しかし、何故にエラーが。何かしらコンパイルオプションをつけないといかんのかしら。それともバージョン違いで起きるのかな。DevKitは、RubyInstaller で公開されてる現行版、4.7.2 20130224 なのだけど。
どうやら MinGW64なら、dsound.h を使ったソースもビルドできるらしい…。そのあたりから辿って、おかげで色々分かってきたり。
- Ruby 1.8.6、1.9.3 用 DevKit は、tdmとやらが使われてる。
- Ruby 2.0.0 32bit版の DevKit は、mingw64-32 が使われてる。-32 は、32bit版用の結果を出力するってこと? 32bit版のRubyなら32bit版のMinGWが使われてる、と思ってたけど、そうではなかったらしい。
- Ruby 2.0.0 x64版の DevKit は、mingw64-64 が使われてる。
- Ruby 1.9.3 用の DevKit には、dsound.h が入ってない。なので、Ruby 1.9.3 + DevKit でビルドしようとするとハマる。
- Ruby 2.0.0 用の DevKit には、32bit版、x64版、どちらにも dsound.h が入ってる。
- MinGW32 と MinGW64 は、ヘッダファイルその他の数が全然違うように見える。MinGW32 のほうが少ない。
ということで、pik で Ruby 2.0.0 に切り替えて、2.0.0用の devkitvars.bat でPATHを変更して、ruby extconf.rb や make をしてみた。
> ruby extconf.rb checking for main() in -ldsound... yes checking for main() in -lole32... yes creating Makefile > make generating ayame-i386-mingw32.def compiling ayame_ruby.cpp In file included from VoiceElementMidi.h:10:0, from ayame_ruby.cpp:12: midi.h: In member function 'long unsigned int CMidi::GetRealTempo() const': midi.h:173:17: error: 'm_nTempo' was not declared in this scope midi.h: In member function 'long unsigned int CMidi::GetTempo() const': midi.h:177:34: error: 'm_nTempo' was not declared in this scope ayame_ruby.cpp: In function 'void Init_ayame()': ayame_ruby.cpp:422:73: warning: deprecated conversion from string constant to 'TCHAR* {aka char*}' [-Wwrite-strings] make: *** [ayame_ruby.o] Error 1midi.h 内でエラーは出るものの、今までと全然違う感じのエラーメッセージが。ヘッダファイルやライブラリファイルの場所も指定する必要無し。こういうことだったのか…。
しかし、何故にエラーが。何かしらコンパイルオプションをつけないといかんのかしら。それともバージョン違いで起きるのかな。DevKitは、RubyInstaller で公開されてる現行版、4.7.2 20130224 なのだけど。
この記事へのツッコミ
[ ツッコミを読む(3) | ツッコむ ]
以上です。
DXRuby Advent Calendar では勝手ながら記事を参照させていだだきました。事後報告ですみません。
お困りの箇所ですが、たぶん直前の行のコメント「分解能」が 0x5c で終わっているからではないでしょうか。
https://sites.google.com/site/fudist/Home/grep/sjis-damemoji-jp
DevKit のコンパイラは UTF-8 対応だったように思いますので、
UTF-8 に変換するか、
S-JIS/CP932 対応のコンパイラを使うか、
簡易的にコメントの後にスペース等の文字を付け足してやるか
をしてやると動くのではないかと思います。
また、Ayame.DLL 用のライブラリがなさそうなので、あらかじめ pexport と dlltool などで .a ファイルを作っておいた方がよいように思います。
http://d.hatena.ne.jp/arakik10/touch/20100504/p1
いずれも試してはいませんので確実ではありません。
解決済みでしたらすみません。
-finput-charset=CP932 -fexec-charset=CP932 というオプションで文字コードを指定するのが正しいやり方のようです。
http://d.hatena.ne.jp/hake/touch/20120505/p1
pexport、dlltool は知らなかったので、これも試してみたいと思います。