“Been here before, couldn’t say I liked it. Do I start writing all this down?”
I don’t know how much time I have lost over the last few years struggling with mysql gem installation issues on OSX. Usually, it just works, but when it doesn’t it can be quite a pain. I have had to deal with slightly different issues more than once, so I decided it was time to learn and document as much as I could about the solution this time. The latest round of issues I ran into were because I had multiple versions of mysql installed using Homebrew. Bundler would appear to install the gem just fine, when I tried to run things I would get:
Library not loaded: /usr/local/mysql/lib/libmysqlclient_r.16.dylib
This was because the mysql library was not located in /usr/local/mysql/lib, but rather /usr/local/Cellar/mysql51/5.1.71/lib/mysql since I had installed it with homebrew. This could be solved with some softlinks, and I had done that in the past, but I wanted to find a better solution.
You can pass build flags to gems and the mysql gem accepts quite a few. You can specify many of the necessary paths explicitly, but my choice was to point it to the mysql_config script which returns the other information. In my case, the command to install the gem was then:
gem install mysql2 -- --with-mysql-config=/usr/local/Cellar/mysql51/5.1.71/bin/mysql_config
This works ok, but I hated to be installing gems manually when a project uses Bundler. So the next task was to figure out how to pass the options through Bundler. The answer turns out to be the bundle-config command. The following will set up bundler to pass the information along:
bundle config build.mysql2 --with-mysql-config=/usr/local/Cellar/mysql51/5.1.71/bin/mysql_config
After that a ‘bundle install’ will get you going. But you might be curious where the information is being persisted. By default, the configuration is global, it is saved in the users .bundle directory. Specifically, it will be saved to ‘~/.bundle/config’. If you work on many projects like I do, and as a freelancer they are even for different customers, this doesn’t seem like the best idea since I might use need to use different options to build different gem versions for each project. The solution is to add the –local flag to the command. So it now becomes:
bundle config --local build.mysql2 --with-mysql-config=/usr/local/Cellar/mysql51/5.1.71/bin/mysql_config
The config option is now saved within the .bundle subdirectory of the current project.