After a colleague showed me the excellent MySQL Workbench the other day I thought I’d install the packaged MySQL on my Macbook, to do a bit of Catalyst developing.

When it comes to extra Perl modules, I always install everything in my home directory, using local::lib - it keeps everything neat and tidy and means I don’t need to install anything under sudo.

However, I’ve just been struggling to get DBD::mysql to work properly with the packaged MySQL. It would compile just fine, but then refused to load for testing, seemingly unable to find the libmysqlclient dynamic library:

#   Failed test 'use DBD::mysql;'
#   at t/00base.t line 21.
#     Tried to use 'DBD::mysql'.
#     Error:  Can't load '/Users/markp/.cpan/build/DBD-mysql-4.018-hYHpKY/blib/arch/auto/DBD/mysql/mysql.bundle' for module DBD::mysql:
dlopen(/Users/markp/.cpan/build/DBD-mysql-4.018-hYHpKY/blib/arch/auto/DBD/mysql/mysql.bundle, 2): Library not loaded:

After a bit of Googling around, various resources led me to the fact the compiled binary was lacking an RPATH. So all I needed to do was link the binary with an RPATH. But it seems things are not as simple on OS X.

According to Joe Di Pol’s blog, OS X works slightly backwards to what most of us from Linux and Solaris backgrounds understand - compiled binaries look at a dynamic library, which in turns says where it is, rather than the traditional way of thinking which is to include a library search path in the compiled binary.

To see what I mean, look at the mysqlclient dynamic library with otool:

DBD-mysql-4.018-hYHpKY$ otool -D `mdfind libmysqlclient.16.dylib`
/usr/local/mysql-5.5.9-osx10.6-x86_64/lib/libmysqlclient.16.dylib: libmysqlclient.16.dylib

There is no path listed there, which means binaries compiled to use the library won’t be able to find it unless it’s in the system search path of /usr/lib.

We can fix this with install_name_tool though:

DBD-mysql-4.018-hYHpKY$ sudo install_name_tool -id /usr/local/mysql-5.5.9-osx10.6-x86_64/lib/libmysqlclient.16.dylib

DBD-mysql-4.018-hYHpKY$ otool -D `mdfind libmysqlclient.16.dylib`

Now when we run the tests:

DBD-mysql-4.018-hYHpKY$ make testPERL_DL_NONLAZY=1 /usr/bin/perl "-MExtUtils::Command::MM" "-e" "test_harness(0, 'blib/lib', 'blib/arch')"
t/00base.t .................. ok
t/10connect.t ............... ok

It works!

There may be a better way to do this, and if I find it I’ll update this post. Otherwise, that works just fine for me.