Create universal files on Mac OS X
I’ve been getting a new server ready, and as usual the only big issues are architecture issues: 32-bit vs. 64-bit. I had to use 64-bit to set up PHP’s MySQL module, but when I went to install Perl’s MySQL module I had to install the 32-bit version over it. In Mac OS X Leopard, Apache runs as 64-bit, but Perl runs as 32-bit.
So I installed the i386 version. But as soon as I did that, PHP stopped working.
[toggle code]
- dyld: Library not loaded: /usr/local/mysql/lib/libmysqlclient.15.dylib
- Referenced from: /usr/lib/php/extensions/no-debug-non-zts-20060613/pdo_mysql.so
-
Reason: no suitable image found. Did find:
- /usr/local/mysql/lib/libmysqlclient.15.dylib: mach-o, but wrong architecture
Of course, when I switched it back to x86_64, Perl stopped working:
[toggle code]
- install_driver(mysql) failed: Can't load '/Library/Perl/5.8.8/darwin-thread-multi-2level/auto/DBD/mysql/mysql.bundle' for module DBD::mysql: dlopen(/Library/Perl/5.8.8/darwin-thread-multi-2level/auto/DBD/mysql/mysql.bundle, 1): Library not loaded: /usr/local/mysql/lib/libmysqlclient.15.dylib
- Referenced from: /Library/Perl/5.8.8/darwin-thread-multi-2level/auto/DBD/mysql/mysql.bundle
-
Reason: no suitable image found. Did find:
- /usr/local/mysql/lib/libmysqlclient.15.dylib: mach-o, but wrong architecture at /System/Library/Perl/5.8.8/darwin-thread-multi-2level/DynaLoader.pm line 230.
- at (eval 3) line 3
- Compilation failed in require at (eval 3) line 3.
- Perhaps a required shared library or dll isn't installed where expected
This is the problem:
- Perl comes installed only as 32-bit.
- Apache runs as 64-bit, which means that the PHP module runs as 64-bit.
- To get PHP to load MySQL requires installing MySQL as 64-bit.
- To get Perl to load MySQL requires installing MySQL as 32-bit.
- There is no combined package install of MySQL for both 32-bit and 64-bit.
The culprit is /usr/local/mysql/lib/libmysqlclient.15.dylib. It is loaded dynamically, so you can’t just install one, get PHP working, then install the other to get Perl working. As soon as you switch to 32-bit, PHP stops working; as soon as you switch to 64-bit, Perl stops working.
Rather than try to compile MySQL to a universal file and worry about that process bringing up its own issues, I thought I’d see if there was an easy way to combine libraries of different architectures into a universal file. There is: lipo.
I extracted the i386 version to a different volume, but you could also extract one, get the libmysqlclient.15.dylib from it, and then extract the other.
- $lipo -create /Volumes/madness/usr/local/mysql/lib/libmysqlclient.15.dylib /usr/local/mysql/lib/libmysqlclient.15.dylib -output libmysqlclient.15.dylib
- $file libmysqlclient.15.dylib
- libmysqlclient.15.dylib: Mach-O universal binary with 2 architectures
- libmysqlclient.15.dylib (for architecture i386): Mach-O dynamically linked shared library i386
- libmysqlclient.15.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
Then, move that file to to /usr/local/mysql/lib and you should be good to go.
Reminder: you can attach DMG files from the command line using hdiutil, and you can install from a package using installer:
Note that the target of the installer is a volume. You can put any path you want there, but it will use the root of the volume the path is on as its installation point.