MySQL Sandbox + Ruby + mysql/mysql2ライブラリの使用方法

去年から仕事(Python)ではMySQL Sandboxを使っていたのだが、MySQL5.6が出たのをきっかけに今回個人PCにRubyでも使い始めた。
で、その時にmysqlのライブラリを入れるのに苦労したのでメモっておく。
環境はMacだがLinuxでも同じ対応で変わらないだろう。


MySQL Sandboxを使うとめんどくさいのが、ライブラリのインストール。
何が面倒くさいかというと、mysqlのライブラリは基本C製なのだが、mysqlの場所が通常の場所にないのでまともにコンパイルできないのがしんどい。

前提

~/sandbox/以下に各バージョンがインストールされているとします。
インストールから説明は面倒くさいので省略します。
Rubyは2.0のpreview2を使っています。

Try編

Rubyの場合は、mysql/mysql2を使うことになりますが解決方法は両方とも同じ。


まずはインストールを何も考えずに行うと以下のようなエラーが。
まあ、これは予想通り。

$ gem install mysql -- --with-mysql-config
Fetching: mysql-2.9.1.gem (100%)
Building native extensions.  This could take a while...
ERROR:  Error installing mysql:
        ERROR: Failed to build gem native extension.

    /Users/longicorn/.rbenv/versions/2.0.0-preview2/bin/ruby extconf.rb
checking for mysql_ssl_set()... *** extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary
libraries and/or headers.  Check the mkmf.log file for more details.  You may
need configuration options.

Provided configuration options:
        --with-opt-dir
        --without-opt-dir
        --with-opt-include
        --without-opt-include=${opt-dir}/include
        --with-opt-lib
        --without-opt-lib=${opt-dir}/lib
        --with-make-prog
        --without-make-prog
        --srcdir=.
        --curdir
        --ruby=/Users/longicorn/.rbenv/versions/2.0.0-preview2/bin/ruby
        --with-mysql-config
        --without-mysql-config
/Users/longicorn/.rbenv/versions/2.0.0-preview2/lib/ruby/2.0.0/mkmf.rb:413:in `try_do': The compiler failed to generate an executable file. (RuntimeError)
You have to install development tools first.
        from /Users/longicorn/.rbenv/versions/2.0.0-preview2/lib/ruby/2.0.0/mkmf.rb:495:in `try_link0'
        from /Users/longicorn/.rbenv/versions/2.0.0-preview2/lib/ruby/2.0.0/mkmf.rb:510:in `try_link'
        from /Users/longicorn/.rbenv/versions/2.0.0-preview2/lib/ruby/2.0.0/mkmf.rb:687:in `try_func'
        from /Users/longicorn/.rbenv/versions/2.0.0-preview2/lib/ruby/2.0.0/mkmf.rb:971:in `block in have_func'
        from /Users/longicorn/.rbenv/versions/2.0.0-preview2/lib/ruby/2.0.0/mkmf.rb:862:in `block in checking_for'
        from /Users/longicorn/.rbenv/versions/2.0.0-preview2/lib/ruby/2.0.0/mkmf.rb:316:in `block (2 levels) in postpone'
        from /Users/longicorn/.rbenv/versions/2.0.0-preview2/lib/ruby/2.0.0/mkmf.rb:286:in `open'
        from /Users/longicorn/.rbenv/versions/2.0.0-preview2/lib/ruby/2.0.0/mkmf.rb:316:in `block in postpone'
        from /Users/longicorn/.rbenv/versions/2.0.0-preview2/lib/ruby/2.0.0/mkmf.rb:286:in `open'
        from /Users/longicorn/.rbenv/versions/2.0.0-preview2/lib/ruby/2.0.0/mkmf.rb:324:in `postpone'
        from /Users/longicorn/.rbenv/versions/2.0.0-preview2/lib/ruby/2.0.0/mkmf.rb:861:in `checking_for'
        from /Users/longicorn/.rbenv/versions/2.0.0-preview2/lib/ruby/2.0.0/mkmf.rb:970:in `have_func'
        from extconf.rb:45:in `
' Gem files will remain installed in /Users/longicorn/src/proj/vendor/bundle/ruby/2.0.0/gems/mysql-2.9.1 for inspection. Results logged to /Users/longicorn/src/proj/vendor/bundle/ruby/2.0.0/gems/mysql-2.9.1/ext/mysql_api/gem_make.out


mysql2でも同じ。エラーメッセージはこっちのほうが分かりやすい。
mysqlとmysql2って何が違うんだろう? Rubyはそこそこ使っているがweb系は初めてなのでさっぱり分からん。

$ gem install mysql2 -- --with-mysql-config
Building native extensions.  This could take a while...
ERROR:  Error installing mysql2:
        ERROR: Failed to build gem native extension.

    /Users/longicorn/.rbenv/versions/2.0.0-preview2/bin/ruby extconf.rb
checking for rb_thread_blocking_region()... yes
checking for rb_wait_for_single_fd()... yes
checking for mysql.h... no
checking for mysql/mysql.h... no
        • -
mysql.h is missing. please check your installation of mysql and try again.
        • -
extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary libraries and/or headers. Check the mkmf.log file for more details. You may need configuration options. Provided configuration options: --with-opt-dir --without-opt-dir --with-opt-include --without-opt-include=${opt-dir}/include --with-opt-lib --without-opt-lib=${opt-dir}/lib --with-make-prog --without-make-prog --srcdir=. --curdir --ruby=/Users/longicorn/.rbenv/versions/2.0.0-preview2/bin/ruby --with-mysql-config --without-mysql-config Gem files will remain installed in /Users/longicorn/src/proj/vendor/bundle/ruby/2.0.0/gems/mysql2-0.3.11 for inspection. Results logged to /Users/longicorn/src/proj/vendor/bundle/ruby/2.0.0/gems/mysql2-0.3.11/ext/mysql2/gem_make.out
さて、MySQLにはmysql_configというコマンドがついてくる。 これでMySQL環境変数のようなのを出力してくれる。
 ~/sandboxes/5.1.68/bin/mysql_config 
Usage: /Users/longicorn/sandboxes/5.1.68/bin/mysql_config [OPTIONS]
Options:
        --cflags         [-I/Users/longicorn/sandboxes/5.1.68/include  -Os -g -fno-common -fno-strict-aliasing -arch i386]
        --include        [-I/Users/longicorn/sandboxes/5.1.68/include]
        --libs           [-L/Users/longicorn/sandboxes/5.1.68/lib -lmysqlclient   -lpthread]
        --libs_r         [-L/Users/longicorn/sandboxes/5.1.68/lib -lmysqlclient_r   -lpthread]
        --plugindir      [/Users/longicorn/sandboxes/5.1.68/lib/plugin]
        --socket         [/tmp/mysql.sock]
        --port           [0]
        --version        [5.1.68]
        --libmysqld-libs [-L/Users/longicorn/sandboxes/5.1.68/lib -lmysqld    -lpthread]
        --variable=VAR   VAR is one of:
                pkgincludedir [/Users/longicorn/sandboxes/5.1.68/include]
                pkglibdir     [/Users/longicorn/sandboxes/5.1.68/lib]
                plugindir     [/Users/longicorn/sandboxes/5.1.68/lib/plugin]
実際github:mysql2/extconf.rbには"mysql_config"を使っている部分がある。 ということは、パスが通っていればOKなはず。 なのだが、PATHを付けてもエラーになる。理由が分からず、ヤル気が出ずにここで1週間ほど潰してしまった。
$ PATH=/Users/longicorn/sandboxes/5.1.68/bin/:$PATH be gem install mysql2 -- --with-mysql-config
Building native extensions.  This could take a while...
ERROR:  Error installing mysql2:
        ERROR: Failed to build gem native extension.

    /Users/longicorn/.rbenv/versions/2.0.0-preview2/bin/ruby extconf.rb
checking for rb_thread_blocking_region()... yes
checking for rb_wait_for_single_fd()... yes
checking for mysql.h... no
checking for mysql/mysql.h... no
        • -
mysql.h is missing. please check your installation of mysql and try again.
        • -
extconf.rb failed ***
Could not create Makefile due to some reason, probably lack of necessary libraries and/or headers. Check the mkmf.log file for more details. You may need configuration options. Provided configuration options: --with-opt-dir --without-opt-dir --with-opt-include --without-opt-include=${opt-dir}/include --with-opt-lib --without-opt-lib=${opt-dir}/lib --with-make-prog --without-make-prog --srcdir=. --curdir --ruby=/Users/longicorn/.rbenv/versions/2.0.0-preview2/bin/ruby --with-mysql-config --without-mysql-config Gem files will remain installed in /Users/longicorn/src/proj/vendor/bundle/ruby/2.0.0/gems/mysql2-0.3.11 for inspection. Results logged to /Users/longicorn/src/proj/vendor/bundle/ruby/2.0.0/gems/mysql2-0.3.11/ext/mysql2/gem_make.out

解決編

正解はこう。
$ PATH=/Users/longicorn/sandboxes/5.1.68/bin:$PATH be gem install mysql2 -- --with-mysql-config
Building native extensions.  This could take a while...
Successfully installed mysql2-0.3.11
Parsing documentation for mysql2-0.3.11
Done installing documentation for mysql2 (2 sec).
1 gem installed
PATHの"bin"の後に"/"がつくと動作がおかしくなってまともに表示しないっぽい。 こんなの分かるか、ボケ。 ただ、5.1、5.6はインストールできましたが、5.5はこれでもエラーになるので何か別問題があるのだろう。 ちなみに、Pythonの場合"mysql-python"というのを使うが、こっちは対策が分からずパッケージをダウンロードしてきて中身を修正して対応した。 そのうち、まともな解決方法を見つけたら、続きで書きます。