Compiling PHP 5.2 on OS X 10.6 Snow Leopard

I recently went through the exercise of compiling PHP 5.2 on Snow Leapord, because Drupal 6 doesn’t behave well with PHP 5.3, which is the version that ships with Snow Leopard. Drupal 7 supports PHP 5.3, but it’s still in development. Even after the release of Drupal 7, there will still be plenty of Drupal 6 sites that require maintenance.

So after a great deal of research and trial and error, I thought that I would put together a summary of what I did and discovered so that others in a similar situation could save themselves the time and frustration.

Originally I was trying to get this to work in 10.5 as well because Leopard was providing php 5.1, but at some point Apple switched to using php 5.2 on Leopard, so I abandoned that effort. Some of the parameters I use were meant to permit proper compilation on 10.5, and I haven’t gone back to verify which ones are no longer needed.

Finally, I want to say that this experience has given me a new appreciation for the craziness that distro maintainers must go through!

Prerequisites

The following needs to be installed for this process to work:

  • XCode
  • MySQL (for the mysql plugin)

Source Files Needed

Note: Many blogs I read suggest rolling your own PCRE library. This is not the best way to do it. PHP already includes a distribution of PCRE in its source tree. I found that if I tried to compile it myself, php would ignore it and use whatever version that came with Apache. This wasn’t a problem on 10.6 because the the version of PCRE included with Apache is fairly recent (v7.9 I believe) but it was disastrous on 10.5 because it had an ancient version of PCRE. Everything would compile just fine but drupal would fail to launch, due to a failing regex check that shouldn’t have been failing. If you really need to use a newer version of PCRE than the one PHP provides, check the ext/pcre directory in the php source code for instructions on how to upgrade the included source.

Compiling

Variable declarations

First, we declare some variables to keep the shell script clean and easy to read:

#work from the current directory BASEDIR=`pwd`
#force everything to get compiled in 64-bit, plus other optimizations.
DEFAULT_CFLAGS="-arch x86_64 -g2 -Os -pipe -no-cpp-precomp"
#The below item is needed because some php won't compile properly without it.
DEFAULT_EXTRACFLAGS="-lresolv" DEFAULT_CCFLAGS="-arch x86_64 -g2 -Os -pipe" 
DEFAULT_CXXFLAGS="-arch x86_64 -g2 -Os -pipe"
#linker flags. Again, forcing 64bit mode. Possibly overkill, but it doesn't hurt.
#Also, bind_at_load allows php to dynamically load any needed libraries provided by
#the operating system. Also, because we're compiling numerous libraries ourselves
#into a custom location, we need to tell the linker where to find our libraries.
DEFAULT_LDFLAGS="-arch x86_64 -bind_at_load -L$BASEDIR/usr/local/lib"
#We want the libraries to compile statically. We also want them installed in a
#temporary folder instead of littering up the OS. 
DEFAULT_CONFIGURE="--enable-static --disable-shared --prefix=$BASEDIR/usr/local"

PNG Library, Jpeg Library, Freetype and MCrypt

There is nothing special about compiling these items. Order is not important. Go into each folder respectively and run the following commands:

CFLAGS="${DEFAULT_CFLAGS}" CCFLAGS="${DEFAULT_CCFLAGS}" CXXFLAGS="${DEFAULT_CCFLAGS}" LDFLAGS="${DEFAULT_LDFLAGS}" ./configure ${DEFAULT_CONFIGURE} 
make 
make install

MHash

You need to have mcrypt compiled before you can do this one.

MHASH_CONFIGURE= "${DEFAULT_CONFIGURE} --with-libmcrypt-prefix=$BASEDIR/usr/local" CFLAGS="${DEFAULT_CFLAGS}" CCFLAGS="${DEFAULT_CCFLAGS}" CXXFLAGS="${DEFAULT_CCFLAGS}" LDFLAGS="${DEFAULT_LDFLAGS}" ./configure ${MHASH_CONFIGURE} 
make 
make install

IMAP

This was was a pain to setup because the build system originated before we had nice standardized processes like configure. Additionally, up until 10.5 OS X did something unusual with one of its libraries that the imap code had to take into account. This was fixed in 10.6 to the standard way of doing things, unfortunately the imap code detects OSX and assumes it needs to do that special tweak. So we need to apply a patch to disable that tweak.

Near the top of imap-2007e/src/osdep/unix/ckp_pam.c, there are a series of lines like so:

#ifdef MAC_OSX_KLUDGE /* why can't Apple be compatible? */ 
#include <pam/pam_appl.h>
#else 
#include <security/pam_appl.h>
#endif

Remove everything but the second include, so that you are left with this:

#include <security/pam_appl.h>

After you apply the patch, you can get down to compiling:

make oxp CC="gcc" EXTRACFLAGS="-fPIC -arch x86_64"

Now, we don’t need everything that gets compiled. Also, there’s no nice convenient install system so we have to do it ourselves:

cd c-client/ 
cp *.h $BASEDIR/usr/local/include 
cp c-client.a $BASEDIR/usr/local/lib/libc-client.a 
ln -svf $BASEDIR/usr/local/lib/libc-client.a 
$BASEDIR/usr/local/lib/c-client.a

PHP

First of all, lets define the flags we will use to compile PHP with. I’ve seen in a couple other blog entries to start the below list with –disable-all to disable everything, and then explicitly add everything manually. I found that this actually broke a couple things so I recommend not using that parameter. Also, I only include here the extensions that do not require custom external libraries in order to compile properly. That permitted some flexibility in experimentation. Also note the different prefix parameter. Since this is the final step in the process, we’re going to put the result into /usr/local.

#all the php bits I want to include
PHPCOMMONFLAGS="--prefix=/usr/local
--enable-static
--disable-shared
--disable-cgi
--enable-bcmath 
--enable-calendar 
--enable-cli
--enable-ctype
--enable-dom
--enable-exif 
--enable-ftp 
--enable-gd-native-ttf 
--enable-hash
--enable-json
--enable-libxml
--enable-mbregex 
--enable-mbstring 
--enable-pcntl
--enable-pcre
--enable-filter
--enable-pdo
--enable-session
--enable-simplexml
--enable-shmop
--enable-soap 
--enable-sockets 
--enable-sqlite-utf8
--enable-sysvsem
--enable-sysvshm
--enable-sysvmsg
--enable-tokenizer
--enable-wddx
--enable-xml --enable-xmlreader --enable-xmlwriter
--infodir=/usr/share/info 
--mandir=/usr/share/man 
--sysconfdir=/private/etc 
--with-apxs2=/usr/sbin/apxs 
--with-bz2=/usr
--with-config-file-path=/etc 
--with-curl=/usr 
--with-gd 
--with-iodbc=/usr 
--with-ldap-sasl=/usr 
--with-ldap=/usr 
--with-libxml-dir=/usr 
--with-mysql-sock=/tmp/mysql.sock 
--with-mysql=/usr/local/mysql 
--with-mysqli=/usr/local/mysql/bin/mysql_config
--with-openssl=/usr
--with-pdo-mysql=/usr/local/mysql
--with-pdo-sqlite
--with-libedit
--with-xmlrpc 
--with-xsl=/usr 
--with-zlib=/usr --with-zlib-dir=/usr
--without-snmp
"

You will want to add the following to merge in the libraries compiled above:

PHPFLAGS=" $PHPCOMMONFLAGS --with-png-dir=$BASEDIR/usr/local --with-jpeg-dir=$BASEDIR/usr/local --with-imap=$BASEDIR/usr/local --with-imap-ssl=$BASEDIR/usr/local --with-kerberos --with-freetype-dir=$BASEDIR/usr/local "

PHP also needs a patch for the iconv extension to compile properly. Open ext/iconv/iconv.c and look for these lines (approximately at line 196):

#ifdef HAVE_LIBICONV 
#define iconv libiconv 
#endif

and change the libiconv to iconv:

#define iconv iconv

Once you update iconv.c, you can get to compiling:

CFLAGS="${DEFAULT_CFLAGS}" CCFLAGS="${DEFAULT_CCFLAGS}" CXXFLAGS="${DEFAULT_CCFLAGS}" LDFLAGS="${DEFAULT_LDFLAGS}" ./configure ${PHPFLAGS} EXTRA_CFLAGS="${DEFAULT_EXTRACFLAGS}" 
make 
sudo make install

The install process should have automatically replaced the existing apache php module with the new one. All you need to do is restart apache and it should start up with the new php version. Use phpinfo() to verify the php version.

I must note that I was unable to get the gettext library to link properly into php. While Drupal can do ok without it, it’s a very useful internationalization library. If someone figures out how to get that going, let me know. ;)

  1. I’m having problems getting imap to compile.

    Mac OS X 10.6.7 MacbookPro xCode 4.0

    I applied the patch properly to get ride of the bug-workaround in 10.5.

    Your line of code:

    make oxp CC=”gcc” EXTRACFLAGS=”-fPIC -arch x86_64″

    disagrees with another example of compiling IMAP which says:

    make osx

    And your lines of code that say:

    cd c-client/
    cp *.h $BASEDIR/usr/local/include
    cp c-client.a $BASEDIR/usr/local/lib/libc-client.a
    ln -svf $BASEDIR/usr/local/lib/libc-client.a
    $BASEDIR/usr/local/lib/c-client.a

    disagree with the other version which says simply:

    sudo cp c-client/c-client.a c-client/libc-client.a

    The alternative is at:

    http://blog.xeonxai.com/2009/12/03/160/

    Can you resolve this difference in compile code for me?

    May 22nd, 2011
  2. I found a couple of goodies at this posting:

    http://www.teamonetickets.com/software/howto-setup-php-apache-mysql-dev-environment-on-snow-leopard.html

    First, the issue of IMAP is handled thus:

    Some HOWTOs out there tell you to use make oxp, which worked on OS X Leopard (10.5), but does not work on Snow Leopard (10.6)

    make osx

    We will need to have some of the c-client files in a place where our PHP configure will look for them. Use a little something found over at the Forums MacBidouille.

    sudo cp c-client/*.h /usr/local/include/
    sudo cp c-client/c-client.a /usr/local/lib/libc-client.a

    Secondly the answer as to how to compile gettext:


    From the gettext homepage: “The GNU `gettext’ utilities are a set of tools that provides a framework to help other GNU packages produce multi-lingual messages.” These instructions were adapted from Imthiaz Blog.

    cd ~/src/
    curl -O ftp://ftp.gnu.org/gnu/gettext/gettext-0.17.tar.gz
    tar -xzf gettext-0.17.tar.gz
    cd gettext-0.17/gettext-tools
    ./configure
    make -j3
    sudo make install

    I’ve adopted the configure command to use your method.

    Thus far I have all the support libs compiled.

    Now to PHP 5.2.latest, to make my system compatible with Drupal 6.

    May 23rd, 2011
  3. Now I can’t get mhash to compile.

    The shell script fails at:

    src/makephp.sh: line 196: –enable-static –disable-shared –prefix=/usr/local –with-libmcrypt: No such file or directory

    Any idea why?

    May 25th, 2011

Add a comment

Comment feed
The better to greet you with
No one will ever see this
Your pride and joy
The reason this comment form exists

The crew behind ASOT

We're a team of interactive, software, and business intelligence experts skilled in the design, construction, and management of online enterprise systems.

Visit The Jonah Group site

Get in touch with us