RubyInstaller 2.1.xでsqlite3を使う

Ruby 2.1系に対応するRubyInstallerが2014年9月にリリースされました。
新しいRubyをWindowsで使うときの悩みが、バイナリgemが提供されていないこと。
新しいRubyのバージョンで、たとえABIが変わっていなくても、バイナリ(dll)が依存するRubyのファイル名(msvcrt-rubyXXX.dll)がバージョン固定なので、2.0系にコンパイルされているバイナリgemパッケージは2.1系では動きません。
よく躓くのがsqlite3とnokogiriなので、ここではsqlite3のインストール方法をメモしておきます。
(よりよい方法に更新しました@2014-10-22)
(バイナリgemが動かない理由が間違っていたので修正しました@2018-02-20)
sqlite3は1.3.10より、Ruby 2.1に対応しています。

sqlite3のgemのロード失敗

2014年10月22日時点では以下のエラーがでて、sqlite3が使えない。

$ gem install sqlite3
Fetching: sqlite3-1.3.9-x86-mingw32.gem (100%)
Successfully installed sqlite3-1.3.9-x86-mingw32
1 gem installed

$ ruby -e "require 'sqlite3'"
C:/Ruby21/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require': cannot load such file -- sqlite3/sqlite3_native (LoadError)
        from C:/Ruby21/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:55:in `require'
        from C:/Ruby21/lib/ruby/gems/2.1.0/gems/sqlite3-1.3.9-x86-mingw32/lib/sqlite3.rb:6:in `rescue in <top (required)>'
        from C:/Ruby21/lib/ruby/gems/2.1.0/gems/sqlite3-1.3.9-x86-mingw32/lib/sqlite3.rb:2:in `<top (required)>'
        from C:/Ruby21/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:135:in `require'
        from C:/Ruby21/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:135:in `rescue in require'
        from C:/Ruby21/lib/ruby/2.1.0/rubygems/core_ext/kernel_require.rb:144:in `require'
        from -e:1:in `<main>'

sqlite3のインストール方法

上記のsqlite3のgemのロード失敗は、sqlite3-1.3.9-x86-mingw32.gemに、Ruby2.1用のバイナリが含まれていないことに起因する。
具体的に言うと、sqlite3-1.3.9-x86-mingw32.gemは、中にRuby1.8, 1.9, 2.0用のsqlite3_native.soが含まれるのだが、2.1用が無い(Ruby 2.1のdllを参照しているものがない)。
そこで、以下の手順でRuby2.1用のsqlite3_native.soを作ってロード可能にしようというのが本件の趣旨。
手順の中で、sqlite3-1.3.9.gemとsqlite3-1.3.9-x86-mingw32.gemを用いるが、sqlite3-1.3.9.gemは上記sqlite3_native.soを作って、sqlite3-1.3.9-x86-mingw32.gemの展開ディレクトリにコピーした後削除する。
これは、gem install sqlite3やbundle installなどとすると、sqlite3-1.3.9.gemが入っているにもかかわらず、sqlite3-1.3.9-x86-mingw32.gemが追加でインストールされ、さらにそちらが優先されてしまって結局ロードで失敗するからである。
なお、本手順は32bit版用で、64bit版の場合は異なるので注意。

  1. RubyInstaller 2.1.3をダウンロードし、インストールする。インストールパスはC:\Ruby21\とする。
  2. 対応するDevKitをダウンロードし、インストールする。インストールパスはC:\DevKit200\とする。
  3. DevKitを適切に設定する
    C:\DevKit200\msys.batを実行して、msys環境のコンソールを開く。

    	$ pushd /c/DevKit200
    	$ ruby dk.rb init
    	$ ruby dk.rb review
    	# configure config.yml if need.
    	$ ruby dk.rb install
  4. sqlite3のamalgamation版のソースコードのアーカイブとWindows用のコンパイル済みdllを公式サイトからダウンロードする。
  5. ダウンロードしたソースコードのアーカイブとコンパイル済みdllを展開する。ソースの展開パスをC:\DevKit200/local/src/sqlite3、Dllの展開パスをC:\Ruby21\binとする。
  6. sqlite3のgemをダウンロード&コンパイルする。
    	$ gem install sqlite3 --platform=ruby -- --with-sqlite3-include=/c/DevKit200/local/src/sqlite3 --with-sqlite3-lib=/c/Ruby21/bin
  7. バイナリ版のsqlite3のgemをインストールしていないなら、インストールする。
    	$ gem install sqlite3
    	Fetching: sqlite3-1.3.9-x86-mingw32.gem (100%)
    	Successfully installed sqlite3-1.3.9-x86-mingw32
    	1 gem installed
  8. コンパイル済みのネイティブエステンションをRubyのbinディレクトリに格納する。
    	$ mkdir /c/Ruby21/lib/ruby/gems/2.1.0/gems/sqlite3-1.3.9-x86-mingw32/lib/sqlite3/2.1
    	$ mv /c/Ruby21/lib/ruby/gems/2.1.0/gems/sqlite3-1.3.9/lib/sqlite3/sqlite3_native.so /c/Ruby21/lib/ruby/gems/2.1.0/gems/sqlite3-1.3.9-x86-mingw32/lib/sqlite3/2.1
    	
  9. 素のsqlite3のgemは不要なので、削除する。
    	$ gem uninstall sqlite3
    	Select gem to uninstall:
    	 1. sqlite3-1.3.9
    	 2. sqlite3-1.3.9-x86-mingw32
    	 3. All versions
    	> 1
    	Successfully uninstalled sqlite3-1.3.9
  10. [本テスト] コマンドプロンプトを立ち上げて、sqlite3のgemがロードできるか確認。
    	> ruby -e "require 'sqlite3'" && echo %ERRORLEVEL%
    	0

    0だったら成功。おつかれさまでした。

Nazy の紹介

A software engineer.
カテゴリー: Programming, Ruby パーマリンク