gem install mysql の変わったハマりかた

結論としては,32bit binary の Ruby と 64bit binary の MariaDB (MySQL) が混在したことによるトラブルでした

当初の環境は以下のとおり :

  • OmniOS x86_64 (Solaris)
  • Ruby 2.1.0
  • MariaDB 5.5.35 x86_64 (MariaDB official binary)

事象

自分でビルドしたRubyは,以下の様に ./configure && gmake したものです

$ gtar zxf ruby-2.1.0.tar.gz
$ cd ruby-2.1.0 
$ ./configure && gmake && sudo gmake install

普通に ruby-mysql gem をインストールしようとすると、失敗します

$ sudo gem install mysql
Building native extensions.  This could take a while...
ERROR:  Error installing mysql:

        ERROR: Failed to build gem native extension.

/usr/local/bin/ruby extconf.rb install mysql
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lm... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lz... yes
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lsocket... no
checking for mysql_query() in -lmysqlclient... no
checking for main() in -lnsl... yes
checking for mysql_query() in -lmysqlclient... no
*** extconf.rb failed ***
...

どうやら extconf.rb が MariaDB のディレクトリパスを見つけられないように見えます。
gemはオプションとして "--" を指定すると, extconf.rb にオプションを渡すことができます。ここでMariaDBのconfigを指定して再実行します

$ sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
Building native extensions. This could take a while...
ERROR: Error installing mysql:
ERROR: Failed to build gem native extension.

sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
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.

→ もっとダメになった

ビルドログは以下の通り:

% less /usr/local/lib/ruby/gems/2.1.0/gems/mysql-2.9.1/ext/mysql_api/mkmf.log
"/opt/gcc-4.7.2/bin/gcc -o conftest -I/usr/local/include/ruby-2.1.0/i386-solaris2.11 -I/usr/local/include/ruby-2.1.0/ruby/backward -I/usr/local/include/ruby-2.1.0 -I. -D_FILE_OFFSET_BITS=64 -I/usr/local/mysql/include/mysql -I/usr/local/mysql/include/mysql/.. -D__sun -m64 -g -O3 -fno-fast-math -ggdb3 -Wall -Wextra -Wno-unused-parameter -Wno-parentheses -Wno-long-long -Wno-missing-field-initializers -Wunused-variable -Wpointer-arith -Wwrite-strings -Wdeclaration-after-statement -Wimplicit-function-declaration conftest.c -L. -L/usr/local/lib -Wl,-R/usr/local/lib -L. -fstack-protector -L/usr/local/mysql/lib -lmysqlclient -lthread -lsocket -lz -lnsl -lm -Wl,-R -Wl,/usr/local/lib -L/usr/local/lib -lruby-static -lpthread -lgmp -lsocket -ldl -lcrypt -lm -lc"
In file included from /usr/local/include/ruby-2.1.0/ruby.h:33:0,
 from conftest.c:1:
/usr/local/include/ruby-2.1.0/ruby/ruby.h:105:14: error: size of array _ruby_check_sizeof_long_ is negative
/usr/local/include/ruby-2.1.0/ruby/ruby.h:109:14: error: size of array _ruby_check_sizeof_voidp_ is negative
...

→ mysql-rubyのコンパイルに失敗してる

このログをGoogle先生に聞いてみると,『MariaDB の 64bit binary を入れるべし』といった結果がヒットします

でも 64bit binary な MariaDB をインストールしているはず......

% file /usr/local/mysql/bin/mysqld
/usr/local/mysql/bin/mysqld: ELF 64bit LSB executable AMD64 Version 1 [SSE], dynamically linked, not stripped 

......

$ file /usr/local/bin/ruby
/usr/local/bin/ruby: ELF 32bit LSB executable 80386 Version 1, dynamically linked, not stripped

アッー

→ MariaDB (64bit Binary) に対して, Ruby (32bit Binary) を宛てがおうとしてしまったのが問題

解決

Ruby (64bit Binary) をビルドする方法は以下のとおり

$ gtar zxf ruby-2.1.0.tar.gz 
$ cd ruby-2.1.0 $ ./configure --with-arch=x86_64 && gmake && sudo gmake install

$ file /usr/local/bin/ruby
/usr/local/bin/ruby: ELF 64bit LSB executable AMD64 Version 1, dynamically linked, not stripped

改めて ruby-mysql gem をインストールして

$ sudo /usr/local/bin/gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
Building native extensions with: '--with-mysql-config=/usr/local/mysql/bin/mysql_config'
This could take a while...
Successfully installed mysql-2.9.1
Parsing documentation for mysql-2.9.1
Installing ri documentation for mysql-2.9.1
Done installing documentation for mysql after 0 seconds
1 gem installed

最後にライブラリパスを通して

$ sudo crle -64 -u -l /usr/local/mysql/lib

おしまい。