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:
libmysqlclient.16.dylib
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
/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`
/usr/local/mysql-5.5.9-osx10.6-x86_64/lib/libmysqlclient.16.dylib:
/usr/local/mysql-5.5.9-osx10.6-x86_64/lib/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/*.t
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.