Rubygems: mysql gem on OS X, getting it to work.

As many of you know, with OS X, it takes a little doing to get Ruby [and Rails] working properly. Installing MySQL and configuring it properly is also a bit of a bear. More than it should be. Then, once you’ve got all of that squared away, while you’re learning all the devilish little details of these fabulous tools, you also have to dive in to using and installing Ruby Gems. Gem is a pretty nice little package management tool. Kind of similar to apt-get on Linux or MacPorts (a.k.a DarwinPorts) or CPAN for Perl, but specifically for installing software libraries for Ruby. Like all of those, gem can seem to easy and good to be true. Sometimes it downright sucks, though. Gem will continue to install a piece of software (a gem) even if the dependencies fail and it may or may not issue any warnings. In other words, it will not stop you from having broken gems that may appear to be installed (when you run gem list any gem will show up in the list, whether or not it is properly installed and functional).

I had thought I installed the mysql gem and that it was working properly. Rails was up and running fine on my Mac, so it only seemed logical. Of course… FOOLISH ASSUMPTION! Apparently Rails ships with its own default mechanisms for dealing with MySQL, so I don’t know much about Rails yet and I was unaware of that. I’m also still honing my sharp-as-a-butter-kife Ruby skills. And this is where I discovered the problem! Once I got to the Ruby database stuff, I found that require 'mysql' just didn’t like me or my kind.

When trying to run a simple file starting with:
require 'rubygems'
require 'mysql'

...

I get this:
/usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `gem_original_require': no such file to load -- mysql (LoadError)
from /usr/local/lib/ruby/site_ruby/1.8/rubygems/custom_require.rb:27:in `require'
from mysql_ruby.rb:3

But when I do a local:
gem list my

I do get this:

*** LOCAL GEMS ***

mysql (2.7)
MySQL/Ruby provides the same functions for Ruby programs that the
MySQL C API provides for C programs.

So I know it is there. Other gems seem fine. irb also says there is no mysql gem.
MySQL is installed and running.

Rather than completely start with new files, since I knew the stuff was there, I figured it just needed a little massaging.
Here is the account I kept of what I did to fix the problem. It’s not the most graceful thing, but it’s not bad:

Part 1: Configuration You Never Knew You Had To Do

mysql gem manual setup for OS X 10.4.9 (probably any 10.4.x)

I’ve got Ruby 1.8.4 installed in /usr/local/bin
(I fixed the bad factory install long ago)

My mysql gem 2.7 is installed in the following directory:
/usr/local/lib/ruby/gems/1.8/gems/mysql-2.7

My MySQL is installed in:
/usr/local/mysql/

(actually in:
/usr/local
I have a symlink to the full name of the install to simplify the path name. I got this idea from the way other software is often installed. (such as the Entropy PHP distro))

You should navigate (in Terminal, using UNIX command cd) your way to each of those directories in separate terminal windows. This should keep you ready to check stuff. To open them as finder windows (much easier to browse) just use OS X’s open command.
open /path/name/here
So, on my machine
open /usr/local/lib/ruby/gems/1.8/gems/mysql-2.7

The terminal window open to the mysql gem’s directory is where you will type all of these commands.

extconf.rb is the main enemy you must do battle with and this fearsome beast has following options:

–with-mysql-include=dir
MySQL header file directory. Default is /usr/local/include
Mine would be
/usr/local/mysql/include
So,
--with-mysql-include=/usr/local/mysql/include

–with-mysql-lib=dir
MySQL library directory. Default is /usr/local/lib
Mine would be
/usr/local/mysql/lib
so,
--with-mysql-lib=/usr/local/mysql/lib

–with-mysql-dir=dir
Same as –with-mysql-include=dir/include, –with-mysql-lib=dir/lib
Mine would be
/usr/local/mysql
So, in theory, I could simply use only :
--with-mysql-dir=/usr/local/mysql

–with-mysql-config[=/path/to/mysql_config]
Get compile-parameter from mysql_config command.
Mine would be
/usr/local/mysql/bin/mysql_config
So,
--with-mysql-config=/usr/local/mysql/bin/mysql_config

Well then, let’s try this all together now, shall we? It’s long…
at the command line:

ruby extconf.rb --with-mysql-include=/usr/local/mysql/include --with-mysql-lib=/usr/local/mysql/lib --with-mysql-dir=/usr/local/mysql --with-mysql-config=/usr/local/mysql/bin/mysql_config

Oops. Error message:

checking for mysql_ssl_set()... /usr/local/lib/ruby/1.8/mkmf.rb:174:in `initialize': Permission denied - mkmf.log (Errno::EACCES)
from /usr/local/lib/ruby/1.8/mkmf.rb:174:in `open'
from /usr/local/lib/ruby/1.8/mkmf.rb:201:in `postpone'
from /usr/local/lib/ruby/1.8/mkmf.rb:541:in `checking_for'
from /usr/local/lib/ruby/1.8/mkmf.rb:600:in `have_func'
from extconf.rb:20

What the hell does that mean?! Well, error messages in Ruby can be a bit cryptic, but mainly because they’re so verbose. This just said you don’t have the matching permissions with those of the file you’re trying access.
So what to do?
Easy! Run the same command again, but start with sudo. (often installing or configuring things at the command line in OS X requires you to do sudo, remember that when simple commands that should work fail.)

sudo ruby extconf.rb --with-mysql-include=/usr/local/mysql/include --with-mysql-lib=/usr/local/mysql/lib --with-mysql-dir=/usr/local/mysql --with-mysql-config=/usr/local/mysql/bin/mysql_config

Password:
(enter your password for your user account)

checking for mysql_ssl_set()... yes
checking for mysql.h... yes
creating Makefile

Done.
Now part 2: The Test.
The documentation says:
ruby ./test.rb [hostname [user [passwd [dbname [port [socket [flag]]]]]]]
Ugly. That’s just too many brackets. Too many optional arguments that are usually not optional to get anything done.
hmm… no file mysql.o
let’s skip the test and see what happens.
(I call this being pragmattic. I tried it, now I’m trying something else, rather than getting bogged down. What could go wrong? The gem isn’t working, so it’s not like I’m going to break it any more than it’s already broken.)

Part 3: Make
Now we run the make file and cross our dirty little fingers.
make
No. No dice.
sudo make
nope, same error. Luckily, I found this earlier and it made sense.
What they said was that you need to add the line
#define ulong unsigned long long
in the mysql.c file in the mysql gem’s directory. If you are unfamiliar with C, just open the file in TextMate and scroll down to the first instance of #define (you will see it near the top of the file). Insert the line after the second #define statement and you should be fine. While you’re there though, just to be safe and secure, add a comment line telling when you added it and why.
Ok, save and close the mysql.c file. Now run make again.
sudo make
Waitingmake often takes time and don’t you dare expect to understand half the gobbledy-gook it spits out. Make also tends to have lengthy periods where there is no feedback on progress and all you can do is wait and wonder. This one is a quickie though.
Ok, that was painless (I hope) now make install:
sudo make install
And that should have been super fast.
Now go play with Ruby and MySQL as you should.

CAVEAT EMPTOR: We didn’t successfully run the test.rb file. That’s too bad. It was designed [presumably] for compiling the gem from source the old-fashioned way. Or perhaps the unit test is out of date, who knows. But it would be nice to know if everything passes! But sometimes we must live dangerously and as we say in Texas:
If it ain’t broke, don’t fix it.

0 comments ↓

There are no comments yet...Kick things off by filling out the form below.

Leave a Comment