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
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.