mieki256's diary



2014/12/30(火) [n年前の日記]

#2 [ruby] Visual C++ で Windows版RubyのC拡張ライブラリがビルドできるか実験

記事の順番が前後しちゃってるけど…。Visual C++ を使って、Windows版RubyのC拡張ライブラリを作れるのかどうかが気になってきたので試したり。

環境は、Windows7 x64 + ActiveScriptRuby 2.0.0 p353 (mswin32版) + VS2010(Visual Studio 2010 Express) + Windows SDK。

_ActiveScriptRuby and Other packages によると、ActiveScriptRuby 2.0.0 は VS2010 のライブラリとリンクしてる、と書いてあるので、VS2010 を利用。

最初、VS2010上でdllをビルドしようとしたけど、出来上がった .dll を .so にリネームして使おうとしても「読み込めねえよ」と文句を言われてしまった。なので、コマンドライン(DOS窓)上でビルドできないか実験。

Windows SDKのインストール。 :

VS2010 に入ってるコンパイラ等をコマンドライン上で使おうとする場合、以下のbatファイルを実行するとビルドに必要な環境変数が設定される。
"C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\vcvarsall.bat" x86

それと、 _Windows SDK for Windows 7 and .NET Framework 4 てのが必要という話を見かけた。

Windows SDKは自分の環境でも以前インストールしてあったはずなのだけど、どうもちゃんと設定されてないところがあったので、アンインストールしてから再インストールしてみたり。

Windows SDK をインストールする際、不具合が3つある。以下の記事で解説されてる。

_Windows SDK for Windows 7.1 をインストールするとエラーが発生する - Microsoft.NET - Project Group
_windows sdk - WindowsSdkDir is not set correctly in Visual Studio 2008? - Stack Overflow

  1. Microsoft Visual C++ 2010 x86 Redistributable、Microsoft Visual C++ 2010 x64 Redistributable のバージョンが新しいと、Windows SDK のインストール時にエラーが出る。
  2. Visual C++ 2010 SP1 がインストールされてると、インストール時にエラーが出る。
  3. レジストリに、Windows SDKのインストール場所が正しく記録されていない。

1. の問題は、Windows SDK インストール前に、コントロールパネル経由であらかじめ Microsoft Visual C++ 2010 (x86|x64) Redistributable をアンインストールしておくことで回避できた。Windows SDK がインストールされれば、そのうち Windows Update で最新版に更新されるらしい。

2. の問題は、Windows SDK インストール時に、Visual C++ Compilers の選択を外してからインストールしてどうにか。その後、 _Windows SDK 7.1 用 Microsoft Visual C++ 2010 Service Pack 1 コンパイラ更新プログラム をインストール。

3. の問題。vcvarsall.bat を実行した際、〜\Common7\Tools\VCVarsQueryRegistry.bat によってレジストリの値が読み取られ、Windows SDK のインストール場所が環境変数 WindowsSdkDir に設定されて、それを元にして環境変数 INCLUDE や LIB が設定されるのだけど。Windows SDK インストール時に、レジストリに場所が記録されてないので、環境変数 INCLUDE や LIB の値がおかしくなってしまう。

仕方ないので、レジストリに自分で追加。WindowsSDKPathSet_HKCU.reg というファイルを作って以下を記述。右クリックして「結合」。
Windows Registry Editor Version 5.00

[HKEY_CURRENT_USER\SOFTWARE\Microsoft\Microsoft SDKs\Windows\v7.0A]
"InstallationFolder"="C:\\Program Files (x86)\\Microsoft SDKs\\Windows\\v7.0A\\"

RubyのC拡張ライブラリをVisual C++でビルド。 :

  1. xxxx.c や extconf.rb を用意。巷の解説ページからコピペしてきたり。
  2. コマンドライン上で vcvarsall.bat を実行。Visual C++ (cl.exe等)が使える状態になる。
  3. ビルドに必要なヘッダファイルやライブラリファイルを、ActiveScriptRuby 2.0.0 のインストールフォルダからコピーしてくる。ruby/ というフォルダを作って、include/ フォルダ内にヘッダファイル(*.h)を、lib/ フォルダ内にライブラリファイル(*.lib)をコピー。
  4. Ruby側からコピーしてきた config.h の最初のあたりに、VC++ のバージョン決め打ちでビルドする記述があるので、場合によってはコメントアウト。
  5. ruby extconf.rb --with-opt-dir=ruby を実行。Makefileが自動生成される。中を覗いたら、コンパイラとして cl が指定されてたので、VC++用に出力された Makefile らしい。MinGW用の Makefile なら gcc とか g++ が指定されてるはず。
  6. Makefile 内のコンパイルオプション等を修正。-MD を -MT に変更。g- と -G6 を削除。-MT にすると静的リンクになるらしい。
  7. nmake を実行。VC++ は nmakeで、MinGW は make。
Init_Xxxx がどうのこうのとエラーが出たけど、関数名を Init_xxxx にしてみたら通った。何故。それでもとりあえず、xxxx.so ができた。

ActiveScriptRuby 2.0.0 (mswin32版) では使えたけれど、RubyInstaller 2.0.0 p451 (mingw版) では動かなかった。

MinGW版Ruby でも動く .so を VC++ でビルドするにはどうしたらいいんだろ…。ライブラリファイルが違うから無理なのかな…。でも、mswin32版用のバイナリなのに、mingw32版Rubyで動くものもあるよな…。どうやって作ってるんだろ…。

Ruby 1.9.2 mswin32版をインストールして同じことを。 :

以下の記事を読んでるうちに、Ruby 1.9.2 mswin32版を対象にしてビルドすれば mingw32版Rubyでも動くC拡張ライブラリができるのでは、と思えてきたので試したり。

_Ruby2.0.0-mswin32版のDXRuby1.4.0 - mirichiの日記
_DXRubyコンパイル - mirichiの日記

_Release - Ruby-mswin32 (ja) から、ruby-1.9.2-p136-i386-mswin32.zip をDLして解凍。任意の場所に置く。この版は VC6.0 でビルドされてるから MinGW と互換性がある、らしい。

pik または uru を使って、他のバージョンのRubyと切り替えて使えるように。

登録。
pik add C:\置いた場所\bin
uru admin add C:\置いた場所\bin

登録されたか確認。
pik list
uru ls

切り替え。
pik 192
uru 192p136

簡単な *.c と extconf.rb を用意して、前述の手順と同じことをしてみたら、*.so ができた。mswin32版Rubyから呼び出せた。試しに、mswin32版Ruby から、mingw版Ruby に切り替えて使ってみても動いた。なるほど、VC6.0 でビルドされた Ruby のアレコレを使えば、mingw版Rubyでも使える、と…。

ayame.so のビルドも試してみた。 :

調子に乗って ayame.so のソースでもやってみた。環境変数 INCLUDE や LIB に、DirectXインストール場所\Include、Lib を追加。LIBPATH に DirectXの .dll が置かれてる場所を追加。そして同じ手順で作業を。

ruby extconf.rb で、「dsound.lib がねえよ」と言われる。もしかして、INCLUDE や LIB は見てくれないのかな…?

extconf.rb の最初の方に、
dir_config("DX")
を追加して、--with-dx-include=xxxx --with-dx-lib=xxxx でDirectXのインストール場所を指定できるようにする。
ruby extconf.rb --with-opt-dir=ruby --with-dx-include="C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Include" --with-dx-lib="C:\Program Files (x86)\Microsoft DirectX SDK (June 2010)\Lib\x86"
今度はエラーが出ない。Makefile が作成できた。

nmake してみた。*.so ができた。ruby sample1.rb を実行。…音が鳴った! MinGW でビルドした版と違って、こっちはちゃんと音が鳴ってる。なるほど、やっぱり VC++じゃないとビルドできないのですな…。ていうか今頃、配布ファイル名に mswin32 とついてることに気付いたりして。何故自分は今まで気づかなかったのか。トホ。

以上です。

過去ログ表示

Prev - 2014/12 - 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