Essays

Essays about Software Development

2 years ago

Wednesday, September 19, 2007

Installing the Ruby mysql-2.7 gem on OS X 10.4

You would think installing the mysql gem for Ruby would be as easy as doing

sudo gem install mysql

Unfortunately, it’s not. If you do a quick Google search you’ll find hundreds of blog posts lamenting the problems with this gem on OS X 10.4, all with varied solutions that don’t work. The command above gives you this:

Select which gem to install for your platform (powerpc-darwin8.8.0)
1. mysql 2.7.3 (mswin32)
2. mysql 2.7.1 (mswin32)
3. mysql 2.7 (ruby)
4. mysql 2.6 (ruby)
5. Skip this gem
6. Cancel installation
> 3
Building native extensions.  This could take a while...
ERROR:  While executing gem ... (Gem::Installer::ExtensionBuildError)
    ERROR: Failed to build gem native extension.

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... no
checking for mysql_query() in -lmysqlclient... no

Gem files will remain installed in /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7 for inspection.
Results logged to /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7/gem_make.out

What it’s complaining about is the fact that it can’t find your MySQL client libraries. You have to pass in the location of your MySQL installation using the following switch:

sudo gem install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config

Many posts regarding the problems with this gem use the switch --with-mysql-dir. Don’t be confused — --with-mysql-config does basically the same thing, but apparently the mysql_config binary provides out all the command-line switches, including --with-mysql-dir, necessary for the installation (according to a comment here). Oh yeah, you did install MySQL in /usr/local/mysql, didn’t you?

OK, so that wasn’t so bad, right? No. For some reason the gem itself has been broken for at least a year. You next get the following error:

Building native extensions.  This could take a while...
ERROR:  While executing gem ... (Gem::Installer::ExtensionBuildError)
    ERROR: Failed to build gem native extension.

ruby extconf.rb install mysql -- --with-mysql-config=/usr/local/mysql/bin/mysql_config
checking for mysql_ssl_set()... no
checking for mysql.h... yes
creating Makefile

make
gcc -I. -I. -I/usr/local/lib/ruby/1.8/powerpc-darwin8.8.0 -I. -DHAVE_MYSQL_H  -I/usr/local/mysql/include -Os -arch ppc64 -fno-common -fno-common -g -O2 -pipe -fno-common  -c mysql.c
mysql.c: In function 'Init_mysql':
mysql.c:2015: error: 'ulong' undeclared (first use in this function)
mysql.c:2015: error: (Each undeclared identifier is reported only once
mysql.c:2015: error: for each function it appears in.)
mysql.c:2015: error: parse error before numeric constant
mysql.c:2018: error: parse error before numeric constant
make: *** [mysql.o] Error 1

A post by Jarkko Laine explains the problem. You must add

#define ulong unsigned long

to the top of /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7/mysql.c.in. I saw mentioned in a few places that this is a bug in the MySQL libraries — whatever the case, the gem author should include this fix in the gem itself to save a lot of people a lot of frustration.

After adding the above line to your mysql.c.in, you can’t simply run gem again, because it will download the gem source anew and overwrite the change you just made. Instead, you have to build and install the gem manually:

cd /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7
sudo ruby extconf.rb --with-mysql-config=/usr/local/mysql/bin/mysql_config
sudo make
sudo make install
sudo make clean

This creates a makefile, and then builds and installs the gem.

So, all working now? No — not at all:

% irb -r mysql
Powermac:/usr/local/lib/ruby/gems/1.8/gems/mysql-2.7% irb -r mysql
/usr/local/lib/ruby/site_ruby/1.8/powerpc-darwin8.8.0/mysql.bundle: Failed to load /usr/local/lib/ruby/site_ruby/1.8/powerpc-darwin8.8.0/mysql.bundle (LoadError)
        from /usr/local/lib/ruby/1.8/irb/init.rb:252:in `load_modules'
        from /usr/local/lib/ruby/1.8/irb/init.rb:250:in `each'
        from /usr/local/lib/ruby/1.8/irb/init.rb:250:in `load_modules'
        from /usr/local/lib/ruby/1.8/irb/init.rb:21:in `setup'
        from /usr/local/lib/ruby/1.8/irb.rb:54:in `start'
        from /usr/local/bin/irb:13

This generic LoadError is so ambiguous that I have no idea what the problem is. It seems like Ruby can’t find the gem after manually installing it. Does anyone have any idea how to fix this?

I emailed (in Japanese, no less) Tomita Masahiro, the author of the gem, as well as the Rubygems mailing list. Tomita ignored me, and the Rubygems mailing list moderator refused to approve my message.

15 Comments

Previous Page