DBD::mysql on OS X Quirks: Architectures, MySQL Binaries and the Filesystem
Oct 6, 2008 / By Nicklas Westerlund
Yesterday evening, a friend of mine had some issues with installing DBD::mysql, and asked if I had encountered the same issue. The problem, as the output from
make test showed, was that certain symbols was missing:
# Tried to use 'DBD::mysql'. # Error: Can't load '/Users/westerlund/src/perl/DBD-mysql-4.008/blib/arch/auto/DBD/mysql/mysql.bundle' for module DBD::mysql: dlopen(/Users/westerlund/src/perl/DBD-mysql-4.008/blib/arch/auto/DBD/mysql/mysql.bundle, 2): Symbol not found: _is_prefix
Fair enough, this is related to a 64-bit issue with MySQL—at least with my Perl version, which is now:
Summary of my perl5 (revision 5 version 10 subversion 0) configuration: Platform: osname=darwin, osvers=9.5.0, archname=darwin-thread-multi-64int-2level
If you try to link to a x86_64 version of MySQL, then you get the above mentioned error. So, I downloaded an x86 version of MySQL and tried again. The output from
cflags (mysql_config) = -I/Users/westerlund/src/perl/mysql-5.1.28-rc-osx10.5-x86/include -g -Os -arch i386 -fno-common -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DIGNORE_SIGHUP_SIGQUIT -DDONT_DECLARE_CXA_PURE_VIRTUAL embedded (mysql_config) = libs (mysql_config) = -L/Users/westerlund/src/perl/mysql-5.1.28-rc-osx10.5-x86/lib -lmysqlclient -lz -lm -lmygcc mysql_config (Users choice) = /Users/westerlund/src/perl/mysql-5.1.28-rc-osx10.5-x86/bin/mysql_config
That looks all good and nice, the right paths, versions and everything. So I compiled it OK, but when running
make test again:
# Error: Can't load '/Users/westerlund/src/perl/DBD-mysql-4.008/blib/arch/auto/DBD/mysql/mysql.bundle' for module DBD::mysql: dlopen(/Users/westerlund/src/perl/DBD-mysql-4.008/blib/arch/auto/DBD/mysql/mysql.bundle, 2): Library not loaded: /usr/local/mysql/lib/libmysqlclient.16.dylib # Referenced from: /Users/westerlund/src/perl/DBD-mysql-4.008/blib/arch/auto/DBD/mysql/mysql.bundle # Reason: image not found at /usr/local/lib/perl5/5.10.0/darwin-thread-multi-64int-2level/DynaLoader.pm line 207.
Okay, that is also a quite easy problem to solve. It couldn’t load
/usr/local/mysql/lib/libmysqlclient.16.dylib because it wasn’t there. But wait a minute, I don’t even have
/usr/local/mysql, so why would it try to load something from there? I was tired, so I just symlinked
/Users/westerlund/src/perl/mysql-5.1.28-rc-osx10.5-x86 and that solved it. The tests went fine and now DBD works like a charm. But I still couldn’t let go of the fact that it was looking somewhere I never told it to. So I checked the Makefile:
$ grep '/usr/local/' Makefile LDDLFLAGS = -arch i386 -arch ppc -bundle -undefined dynamic_lookup -L/usr/local/lib LDFLAGS = -arch i386 -arch ppc -L/usr/local/lib INSTALLSITEBIN = /usr/local/bin INSTALLVENDORBIN = /usr/local/bin INSTALLSITEMAN1DIR = /usr/local/share/man/man1 INSTALLVENDORMAN1DIR = /usr/local/share/man/man1 INSTALLSITEMAN3DIR = /usr/local/share/man/man3 INSTALLVENDORMAN3DIR = /usr/local/share/man/man3 CCFLAGS = -arch i386 -arch ppc -g -pipe -fno-common -DPERL_DARWIN -no-cpp-precomp -fno-strict-aliasing -Wdeclaration-after-statement -I/usr/local/include
That looks okay. Perhaps
mysql_config gave it the idea of going there?
$ ./mysql_config Usage: ./mysql_config [OPTIONS] Options: --cflags [-I/Users/westerlund/src/perl/mysql-5.1.28-rc-osx10.5-x86/include -g -Os -arch i386 -fno-common -D_P1003_1B_VISIBLE -DSIGNAL_WITH_VIO_CLOSE -DSIGNALS_DONT_BREAK_READ -DIGNORE_SIGHUP_SIGQUIT -DDONT_DECLARE_CXA_PURE_VIRTUAL] --include [-I/Users/westerlund/src/perl/mysql-5.1.28-rc-osx10.5-x86/include] --libs [-L/Users/westerlund/src/perl/mysql-5.1.28-rc-osx10.5-x86/lib -lmysqlclient -lz -lm -lmygcc] --libs_r [-L/Users/westerlund/src/perl/mysql-5.1.28-rc-osx10.5-x86/lib -lmysqlclient_r -lz -lm -lmygcc] --plugindir [/Users/westerlund/src/perl/mysql-5.1.28-rc-osx10.5-x86/lib/plugin] --socket [/tmp/mysql.sock] --port  --version [5.1.28-rc] --libmysqld-libs [-L/Users/westerlund/src/perl/mysql-5.1.28-rc-osx10.5-x86/lib -lmysqld -lz -lm -lmygcc]
Nope, there is no reason whatsoever that it should look in
/usr/local/mysql, so I am still not sure why it is. Looking through the files, I can find a couple possible reasons as to why this is happening:
pkglibdir='/usr/local/mysql/lib'set as default in the binary releases.
- mysql itself is configured with
--prefix=/usr/local/mysqlfor binary releases, which also shows in the actual library that we are trying to load:
$ strings libmysqlclient.16.dylib | grep /usr/local/mysql /usr/local/mysql/etc /usr/local/mysql/share /usr/local/mysql
As for why it looks there, I don’t know. I do know, however, that if you follow the common practice of symlinking
/usr/local/mysql to your local tarball installation of mysql, this symptom would not exist. But, what would still exist is the issue of DBD trying to load from
/usr/local/mysql even though nothing tells it to do so. Maintenance is also easier when symlinking, as you don’t have to change paths when upgrading (just redo the symlink). Still, I fail to see why this would be required to install DBD::mysql.