MySQL and PDO on OS X Leopard, Intel

(NOTE: Make sure you read the comments for this post, as there's a better way to get around the 64-bit/32-bit problem without having to compile things. --Tom)

I don't know if I'm missing something big, but getting Perl, Apache, PHP, PDO and MySQL to play nice on my Mac OS X 10.5 install on my Intel Core 2 Duo (Penryn) MacBook Pro hasn't been easy. This is partly thanks to Apache being compiled with x86_64 support, and Perl with i386 only.

64ishAnyway, Googling about, I notice that others have tried this arrangement with varying degrees of success. The easy answer is to install something like MAMP or replace the Apache and PHP installation with a custom build.

However, I prefer to keep my installation as stock as possible, and I'm not a huge fan of proprietary packaging systems like MacPorts and Fink. Don't get me wrong: those systems do what they're meant to do, and as a long-time FreeBSD user, I appreciate the approach. However, they don't fit into the Mac mindset too well, plus I'm too lazy to keep them up-to-date.

In other words, I want Apple to do it all for me, via Software Update where possible. The aim is to keep the stock Apache, PHP and Perl in place, and just add stuff.

The 10.5.3 Apache install does include PDO, but it's fairly crippled: the only drivers are the SQLite ones, even though standard "mysql" support is included. So, "pdo_mysql" will need to be installed... no problem: just install it as a module. But which architecture?

Since 10.5.3 Apache is compiled for i386 and x86_64, it'll run by default as 64-bit, requiring the 64-bit MySQL client libraries.

However, the included 10.5.3 Perl build is compiled only for i386, so if you want to build DBD::mysql for Perl as well, you'll need 32-bit MySQL client libraries.

The MySQL 5.1 official Leopard binary isn't currently a universal build, so right now if you download a binary distribution, you have to pick either 32-bit i386, or 64-bit x86_64. This will knacker either PHP/PDO (64-bit) or Perl/DBI (32-bit) So, assuming we don't want to replace -- or otherwise mess with -- the stock Apache, Perl and PHP, recompiling MySQL seems the way to go: we need to build a fat MySQL with both architectures.

To do this, download the MySQL source (I'm using 5.1.25), unzip and compile with something like:

MACOSX_DEPLOYMENT_TARGET=10.5 \
CFLAGS='-O3 -fno-common -arch i386 -arch x86_64 -arch ppc7400 -arch ppc64' \
LDFLAGS='-O3 -arch i386 -arch x86_64 -arch ppc7400 -arch ppc64' \
CXXFLAGS='-O3 -fno-common -arch i386 -arch x86_64 -arch ppc7400 -arch ppc64' \
./configure \
'--disable-dependency-tracking' \
'--prefix=/usr/local/mysql' \
'--localstatedir=/usr/local/mysql/data' \
'--libexecdir=/usr/local/mysql/bin' \
'--with-comment=MySQL Community Server (GPL)' \
'--enable-thread-safe-client' \
'--enable-local-infile' \
'--with-big-tables'

make

sudo make install

You'll then probably want to do something like:

sudo -s

cd /usr/local

export MYSQL_VERSION=mysql-`mysql/bin/mysql_config --version`-osx10.5-universal

mv mysql $MYSQL_VERSION

ln -s $MYSQL_VERSION mysql

chown -R _mysql:staff $MYSQL_VERSION

cd mysql

ln -s share/mysql support-files

ln -s var data

bin/mysql_install_db --user=_mysql

I'm not sure whether this is the right procedure, but it works for me. A lot of this will change depending on your requirements and circumstances, so don't blame me if it kills your pets.

Next up is to install the PDO_mysql module. This is easy. Firstly, download the PHP source. As of Mac OS X 10.5.3, the current PHP is 5.2.5, but I downloaded 5.2.6 and it seemed fine. Unzip it, and go into the distribution directory (ie. php-5.2.6)

Then:

cd ext/pdo_mysql

phpize

MACOSX_DEPLOYMENT_TARGET=10.5 \
CFLAGS='-O3 -fno-common -arch i386 -arch x86_64 -arch ppc7400 -arch ppc64' \
LDFLAGS='-O3 -arch i386 -arch x86_64 -arch ppc7400 -arch ppc64' \
CXXFLAGS='-O3 -fno-common -arch i386 -arch x86_64 -arch ppc7400 -arch ppc64' \
./configure --prefix=/usr --with-pdo-mysql=/usr/local/mysql

make

sudo make install

You might need to add the following line to /etc/php.ini (creating that file, if necessary):

extension=pdo_mysql.so

Then, restart Apache and you should have a working PDO_mysql driver.

Installing DBD::mysql for the stock Perl is a different matter. If you just do a CPAN install, then the multiple -arch tags that the mysql_config from your new Universal build of MySQL will return are going to foul it up. So instead, you can just build DBD::mysql for i386, as Perl is going to be running in 32-bit mode anyway.

There are probably better, easier ways of doing this, but I resorted to just doing a manual DBD::mysql build, stating the flags by hand:

perl Makefile.PL \
 --cflags="-I/usr/local/mysql/include/mysql -Os -arch i386 -fno-common" \
 --libs="-L/usr/local/mysql/lib/mysql -lmysqlclient -lz -lm"

make

sudo make install

Anyway, if you can think of any improvements to the above routine, your comments are welcome.

Tags

Tracking

Comments

  1. I just noticed that this PHP installation prevents command-line PHP from working correctly, with the error:

    dyld: NSLinkModule() error
    dyld: Symbol not found: _core_globals
      Referenced from: /usr/lib/php/extensions/no-debug-non-zts-20060613/pdo_mysql.so
      Expected in: dynamic lookup
    

    I suspect that this is because the php command is compiled 32-bit only. I'm not sure of the "proper" way to fix this, but I got around it by using a different php.ini file for Apache.

    First, delete the /etc/php.ini file (or at least, remove the offending extension lines)

    Then, create /etc/apache2/php.ini with the extension lines.

    Then, add:

            PHPIniDir /etc/apache2
    

    to the middle of /etc/apache2/other/php5.conf

  2. Another possible option would be to ignore this entire article, avoid the whole 64-bit mess and force Apache into 32-bit mode.

    Since the original Intel Macs used 32-bit Core processors, rather than the 32/64-bit Core 2, the version of Apache must be capable of running 32-bit, so there shouldn't be anything in Mac OS X that needs 64-bit Apache... right?

    I can think of two ways of forcing this: either modifying httpd by using lipo to remove all but the i386 executable, or by overriding /System/Library/LaunchDaemons/org.apache.httpd.plist

    Rather than modifying the file in /System/Library which is rarely a good idea, just override it by copying /System/Library/LaunchDaemons/org.apache.httpd.plist to /Library/LaunchDaemons/org.apache.httpd.plist and change:

                    <string>/usr/sbin/httpd</string>
                    <string>-D</string>
                    <string>FOREGROUND</string>
    

    to

                    <string>arch</string>
                    <string>-i386</string>
                    <string>/usr/sbin/httpd</string>
                    <string>-D</string>
                    <string>FOREGROUND</string>
    

    Activate it by rebooting or:

    sudo launchctl unload /System/Library/LaunchDaemons/org.apache.httpd.plist
    sudo launchctl load /Library/LaunchDaemons/org.apache.httpd.plist
    

    Anyway, I don't know if this approach will work, but you should be able to operate everything in 32-bit mode, which should be a lot simpler. Use the standard 32-bit PDO, MySQL and so forth. If you actually need a 64-bit Apache, then you're on your own... the approach in the article above might be the way to go.

  3. Thanks Tom for this great article ! Facing the same problem, I did the following, based on your suggestion:

    - Install mysql (32 bit) from the package on mysql web site
    - Compile & install the pdo_mysql extension
    - Force apache to run in 32 bit following your advice

    It works great; now having PDO_MYSQL both in Apache and command line PHP.

  4. You could save us some time giving the compiled packets for x86_64 ;-)

  5. Heh... and keep track of all the versions? I think not! :)

    Anyway, I'm convinced the 32-bit mode approach in the comments above is a far better way than I suggested in the main body of the post.

  6. Thanks for the article. Good Information is rare in the MAC PHP development area. Forcing apache to run in 32 bit also allows you to use extensions packaged with other distributions like MAMP free and get things like mcrypt to work to allow you to run packages like Magento.

  7. I did follow your instructions installing PDO_mysql ... for some reason apache is unable to load the extension. The extension is installed in the right directory and the path where apache is looking for the extension is right. Here is the erro I get in in the apache error log:

    [Mon Sep 15 01:20:19 2008] [warn] Init: Session Cache is not configured [hint: SSLSessionCache]
    PHP Warning: PHP Startup: Unable to load dynamic library '/usr/lib/php/extensions/no-debug-non-zts-20060613/pdo_mysql.so' - (null) in Unknown on line 0
    [Mon Sep 15 01:20:19 2008] [notice] Digest: generating secret for digest authentication ...
    [Mon Sep 15 01:20:19 2008] [notice] Digest: done
    [Mon Sep 15 01:20:19 2008] [notice] Apache/2.2.8 (Unix) mod_ssl/2.2.8 OpenSSL/0.9.7l DAV/2 PHP/5.2.6 configured -- resuming normal operations

    Any idea/advice would be greatly appreciate it.

    Thank you for your time.

  8. No idea, sorry... it could be one of many different possible problems.

  9. Hey Raz (any anyone else with that same problem), I ended up with the same situation here on an Intel machine, the reason for me was that that computer's enter LAMP setup (Mac OS 10.5, Apache 2, MySQL 5, PHP 5, nothing to do with the commercial “MAMP” package) is 64-bit. And, I had an old pdo_mysql.so module which was compiled against the wrong version of MySQL. So my solution was to follow the above compiling instructions, but modify the config command:


    MACOSX_DEPLOYMENT_TARGET=10.5 CFLAGS='-O3 -fno-common -arch x86_64' LDFLAGS='-O3 -arch x86_64' CXXFLAGS='-O3 -fno-common -arch x86_64' \
    ./configure --prefix=/usr --with-pdo-mysql=/usr/local/mysql

    …basically, I removed the 32-bit Intel directives, the PowerPC directives, and also made sure that my MySQL path was correct. For example, a port install of MySQL, and including PowerPC and Intel 32 bit versions might be:


    MACOSX_DEPLOYMENT_TARGET=10.5 CFLAGS='-O3 -fno-common -arch i386 -arch x86_64 -arch ppc7400 -arch ppc64' LDFLAGS='-O3 -arch i386 -arch x86_64 -arch ppc7400 -arch ppc64' CXXFLAGS='-O3 -fno-common -arch i386 -arch x86_64 -arch ppc7400 -arch ppc64' \
    ./configure --prefix=/usr --with-pdo-mysql=/opt/local/lib/mysql5/mysql

    Hope this helps!

  10. THANKS! Worked out great!

  11. Yeah, it sucks big time. Was a pain in the ass to get mod_perl working properly, as apache is 64 bit and perl is 32 bit.

    Ended up rolling my own apache though.

    Btw, think the arch stuff can be set globally with just ARCHFLAGS='-arch x86_64 '

  12. ARGHFLAGS is for controlling the compiler, right? I couldn't find a way of setting the execution architecture mode of the entire machine.

    I set up a couple of command line aliases to twiddle ARCHFLAGS for different compilation modes, but ended up going with the launchd method above.

    However, I have noticed that the /Library/LaunchDaemons override doesn't seem to be working now. Instead I've had to end up changing /System/Library/LaunchDaemons/org.apache.httpd.plist instead. I really don't like changing anything in /System though, but /Library didn't seem to be taking precendence (which I think is wrong).

  13. typo:

    ln -s var data

    instead of:

    ln -s /var data

    cheers

  14. cirpo: that was intentional. The "data" symlink refers to the "var" subdirectory of the mysql tree, ie. /usr/local/mysql/var in this example, referred to as "localstatedir" in the MySQL build, rather than the system-wide /var.

    However, you may wish to either share a var or data directory between all mysql versions, or a separate var for each build. It depends on taste and also the particular needs of your environment.

    If you want to use /var, then a subdirectory should be made, eg. /var/db/mysql and that path compiled in.

    Thanks

  15. I tuought it was a typo beacause when i type 'ln -s var data' I have an error : the directory data doesn't exist.
    It will exist after 'bin/mysql_install_db --user=_mysql'.
    am I doing something wrong?

    cirpo

  16. Strange... the reason for that line is to create "data" for mysql_install_db to install into. An alternative is to just create a "data" directory with mkdir.

    To be honest, since I found out how to flip Apache into 32-bit mode (as shown in the comments above), I just use the standard 32-bit binary distributions of MySQL rather than compiling my own.

  17. Thanks for the write up. I'm having some trouble with the compile command. What would this be for a MBP 32 bit?

    The ones provided result in this error:

    "configure: error: C compiler cannot create executables"

    Anyone come across this problem?

  18. The last time I had an error like that, I'd forgotten to install a C++ compiler on a Linux box. Make sure you have Apple's Developer Tools correctly installed. Other than that, I don't know.

  19. Yes it is strange. Developer Tools are definitely installed and running, and other compiler tasks have completed without issue. Managed to get GD Tools happening, but PDO is the last little hitch. Looks like I might have to resort to *cough* MAMP after all. Cheers anyway.

  20. Forcing apache to run in 32 bit mode works perfectly for me. I'm using native php and apache2 from macosx. To develop with symfony 1.2, I had to get the pdo_mysql from pecl.php.net and mv the compiled extension in the php extension_dir (/usr/lib/php/extensions/).

    I just hope upcoming macosx updates won't screw up my setup!

  21. Tom, great guide
    while I agree that it is more convenient for normal users to force 32bit execution of apache and just avoid the whole 64bit headache.

    -- I used your guide with some modifications to come up with a full 64bit python web stack

    see http://blog.captnswing.net/2009/04/19/python-mod_wsgi-64bit-mac-os-x-105/

  22. I've not been doing PHP on my mac for a while, but have just revisited it again, using PDO and MySQL 5.1 client libraries.

    What a nightmare!

    The problem is that Apple's PHP is compiled with mysql/mysqli support built-in using the 5.0.67 MySQL client library. I'm not sure if it's statically linked or not.

    Anyway, I can't see a way to compile PDO_MYSQL as a shared extension but statically linking in the 5.1 client library. So, while it compiles against the 5.1 library, it seems to run with the 5.0.67 library. This is verified using phpinfo().

    As a result, queries _seem_ to work, but don't always return the correct results.

    While I usually try to stick with the stock Leopard php module, I'm admitting defeat and compiling a new one. Rather than using one of the standard PHP bundles, I'm compiling a fresh one using Apple's configuration parameters (also from phpinfo()), but removing the mysql and mysqli extensions.

    I'm then going to compile those as dynamic extensions THE WAY APPLE SHOULD HAVE IN THE FIRST PLACE!

    Apple, if you're listening/googling, if you're going to include a PHP, please just include a very bare-bones install without compiling in any extensions that can be dl'ed instead! I understand why the stock PHP doesn't include every extension under the sun (good plan), but there's no reason why it needs to include some extensions that limit future expandability.

    Okay, the PDO ext needs to be static on Darwin, but the mysql, mysqli, pdo_sqlite extensions would work perfectly well if dl'ed rather than statically linked, and it would make upgrading MUCH easier.

  23. I can't believe what a pain it is to get pdo_mysql working on my Intel MBP. Over the last week or so I've gotten 3 fairly well customized CentOS servers up and running with perfect LAMP setups, mostly using the yum package manager, and things "just worked". Now I'm trying to get my local dev environment setup to actually get some programming done, and I find that Apple has left me out in the cold - things are far from "just working".

    Using your (very nice, btw) instructions, on the ./configure line, I'm getting the error:

    "configure: error: Try adding --with-zlib-dir=. Please check config.log for more information."

    I come from the days before RPM's and yum, so I'm no stranger to compiling things from src and dealing with dependencies...I just would never have guessed that my Mac would be the thing that blasted me back 10 years to having to pick through config.log files to hammer a silly little .so into submission. :(

    If anyone has any advice on what problem is indicated by that zlib error, I would be very grateful...off to dependency purgatory I go...

  24. Hi,
    thanks for the article.
    I just want to add that if you already have installed a 32-bit MySQL (like me) the way to force Apache to 32-bit arch
    is absolutely faster (and works).

    @ stephenrs, About the zlib error actually if you checkout config.log you will find that is not able to use some library due to a different architecture (it's not the very last line but it's some line before). You are probably compiling a 32 bit extension and trying to use a 64 bit library.

    Bye

  25. It would be a great idea to add the Mac OS X sock path in configuration : --with-unix-socket-path=/var/mysql/mysql.sock

    Also these instructions works on 10.6 (MySQL build only, PDO module build is no longer required) with some adjustments: remove -arch ppcXXX and replace 10.5 with 10.6.

    However you will probably want to add pdo_mysql.default_socket=/var/mysql/mysql.sock in your php.ini. The default Apple installation has not configured the module correctly.

  26. Dear Tom,
    your article on pdo_mysql problems on Mac default PHP istallation is obviously a hit (first place in google search). In your comment from May 23rd, 2009 you've mentioned that you are going to complie PHP yourself and add pdo_mysql manually.
    I was just wondering if you could provide us with a full description how you did it - similar to the one in this article. I'm sure it will be another hit.
    Thank you in advance!
    Andrey

  27. Hey Andrey,

    Thanks for the comments! A lot of this is no longer necessary thanks to Snow Leopard, and I still think recompiling the stock PHP is a Bad Idea... In general, I do my best to avoid changing anything that Apple considers to be core system software, eg. /System. In general, if the PHP needs configuring properly, I think it's worth doing in a separate tree, like MacPorts does.

    ...but it's all about knowing when to bend the rules, too :)

    To elaborate on the phpinfo() step, at the Terminal, type:

    php -i | grep 'Configure Command'

    That should return the command Apple used to configure the PHP build. After tweaking and running that line, it's just a make && sudo make install.

  28. [...] If you’d like the full details to build the extension yourself – see Tom Gidden’s post with all the info. [...]

  29. Hi Tom,
    Thanks for the article. I had to make a couple of changes when implementing it on my system:

    1) ./configure couldn't find my zlib dir, so I had to edit .setup.sh to be:

    ./configure --prefix=/usr --with-pdo-mysql=/usr/local/mysql --with-zlib-dir=/usr/lib/

    2) The original .setup.sh wants to build every architecture, and this seemed to be failing with everything except i386. But you already established that you only need the i386 version. So I modified the script to be:

    CFLAGS='-O3 -fno-common -arch i386' \

    3/ I had to tell php.ini where the .so file was:

    extension_dir = "/usr/lib/php/extensions/no-debug-non-zts-20060613/"

    4/ The trick of creating /Library/LaunchDaemons/org.apache.httpd.plist was fine for a reboot of the computer, but didn't work when you bounced Apache through System Preferences. In the later case Apache still came up in x64 mode. I had to edit /System/Library/LaunchDaemons/org.apache.httpd.plist to get the system to always come up in i386 mode

  30. Hi , i have found this page by googling the phrase below which i am getting almost once a day in my wordpress error log, this phrase brought me to your blog so I hope that here are some experts who are talking about this:

    PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/lib/php/extensions/no-debug-non-zts-20060613/pdo_mysql.so' - /usr/local/lib/php/extensions/no-debug-non-zts-20060613/pdo_mysql.so: cannot open shared object file: No such file or directory in Unknown on line 0,

    Thanks to the error up and below(with some referrer from China) I have my WordPress website once a day or 2 days down - 505 internal server error. To make my website run again I always need to delete .htaccess file .
    Can anybody help me to explain what is wrong , has my website been hacked or what those errors means? I'm sure that foreign URLS is something that in my errors cant be :

    [Sun May 23 03:40:59 2010] [error] [client 213.5.70.184] PHP Warning: PHP Startup: Unable to load dynamic library '/usr/local/lib/php/extensions/no-debug-non-zts-20060613/pdo_mysql.so' - /usr/local/lib/php/extensions/no-debug-non-zts-20060613/pdo_mysql.so: cannot open shared object file: No such file or directory in Unknown on line 0, referer: http://forum.vipearn.com/thread-10523-1-1.html

    Can anybody help me to explain how to eliminate this problem? Unfortunately im not PHP - Apache expert at all ,
    I would be very happy if anybody can respond , Daniel

Leave a Reply

Powered by WP Hashcash