Compiling PHP with OCI8/Oracle, Apache and MySQL on Mac OS X Leopard

Note

This tutorial is for Mac OSX 10.5 “Leopard”. For 10.6 “Snow Leopard” see Compiling PHP with OCI8/Oracle on Mac OS X Snow Leopard

Update 2009-08-09

I have officially switched to PHP 5.3 and updated instructions for the JPEG and PNG libraries.

Note: I did not use the new MySQL Native Driver mysqlnd. More on that in the MySQL section.

Marc Liyanage provides binaries again and even has a custom build system. He manages to compile 4-way binaries for i386, ppc, x86_64 and ppc_64 and provides an installer. You can use this in conjunction with the Apache server OSX already ships with.

Update 2009-07-01

Oracle 10g Release 2 natively on OS X Leopard: Installing Oracle Natively on OS X Leopard. I’m not crazy enough to actually try this, though.

Update 2009-03-11

Thanks to Alejandro Leiva for pointing out an error in the jpeg instructions. Previous instructions did not build/install the library needed to compile the gd extension using the --with-jpeg-dir configure switch. Corrected.

Update 2009-02-27

PHP 5.2.9 has been released. I have updated all used libraries to the latest versions and fixed a small bug in the tutorial regarding the --with-mysql option when configuring php.

Update 2008-12-05

PHP 5.2.7 has been released. The EXEEXT bug is fixed now. Also I have added pdo_oci Support. Turns out the configure script is looking for .so files while on a mac shared libraries are called .dylib. So the fix is as easy as ln -s libclntsh.dylib libclntsh.so. A quick test using Zend Framework confirms it is working.

Also it does not seem to be necessary anymore to explicitly call make install-cli.

Unfortunately my OCI/LOB bug still has not been fixed.

Update 2008-10-25

Now with imap extension.

Intro

My motivation for this tutorial was mostly to get Oracle/OCI support compiled into PHP.

Leopard comes with Apache and PHP, so why should I go through the hassle of compiling it myself? Well, there are several reasons:

Although Mac OS X brings pecl and the phpize tool which lets you compile extensions from source specifically for the installed php version/configuration so compiling PHP is not necessary just to install extensions.

Setup

I assume you have a recent Mac with an Intel® processor and that you are an admin user on your computer.

From here on you will be using the Terminal. In Finder navigate from “Applications” to “Utilities” and start Terminal.

I have to put a disclaimer notice in here. From the Terminal it is easy to delete all kinds of files, like system files or your important data. I can not be held responsible for the outcome when you follow and especially when you do not follow my instructions below.

Basic knowledge

You might have set up a password for your user account. To install software you have to be superuser (root) and you will have to enter your password for that. This is what the sudo command does. It runs the command specified as argument as superuser. It is needed in step 5 below.

The steps to install programs and libraries are as follows:

  1. Downloading the source code

    Downloading from the Terminal is easy with the curl command. You just give it the URL and tell it to save the file instead of displaying it. Example: curl -O ftp://ftp.gnu.org/gnu/gettext/gettext-0.17.tar.gz This will create a file gettext-0.17.tar.gz in the current directory.

  2. Extracting the source code

    All the packages you will download are archived. Usually as .tar.gz or .tar.bz2 files. Unarchiving the files is easy with the tar command. Example: tar xzf gettext-0.17.tar.gz. This will extract the directory structure from that archive in the current directory. in most cases it will create a folder with the same name of the archive file w/o the extension: gettext-0.17 in this case.

  3. Configuring

    Here you can/must set up arguments and (de)activate features of the program to be installed. These are specific to every program. The command used to do this is in most cases ./configure. It will check your system capabilities and set up the program the way you specify.

  4. Compiling & Linking

    make. This is the phase where you just let the computer compile the source code to create the program and relax.

  5. Installing

    This basically just means copying the compiled program and its documentation and library files to the correct places on your system. This has to be done as superuser, hence sudo make install.

Configuring is generally the hard part.

/usr/local

The best way to install custom software is putting it somewhere it won’t disturb the other programs on your system. You do not want to overwrite e.g. the PHP version OS X shipped with (It can be found in /usr/bin/php). Other applications/programs might depend on it.

So now go and create /usr/local. Most configure scripts will use /usr/local as prefix if it exists. In Terminal enter the following.

sudo mkdir -p /usr/local

Next we have to tell the computer to actually look for programs in /usr/local (e.g. when you type php in Terminal you want the correct PHP version to run) and to prioritize them to the built-in ones. That means setting the search path. To do this open or create a file called .bash_login in your home directory with the following command.

touch ~/.bash_login
open -a TextEdit ~/.bash_login

Or if you have TextMate installed:

mate ~/.bash_login

If you follow my example throughout the tutorials on where to install the programs you will compile then these are the corrects paths. If you change the path for, say Apache, you might need to adapt it in this file, too. For now paste

export PATH="/usr/local/bin:\
/usr/local/sbin:\
/usr/local/mysql/bin:\
/usr/local/apache2/bin:\
/usr/local/php5/bin:\
$PATH"

to the file or alter an existing entry accordingly and save the changes. Now you just need Terminal (actually, the shell) to interpret that file right now:

. ~/.bash_login

When you start a new shell, that is a Terminal window or tab this file will be loaded automatically.

For more in-depth information see Dan Benjamin’s great article at hivelogic.com: Using /usr/local.

Last preparations

Create a new directory where all the program source code will be going to.

mkdir php_compiling
cd php_compiling

Compiling

You can’t just download and compile PHP on its own if you need support for, say MySQL (which I assume you do). So you will have to install MySQL first (You’d just need the client libraries and headers to compile against, but I could not find those as a download option on the MySQL site). Or you can compile it on your own while you are at it.

The next sections will each be about one specific program or library that is needed for PHP to compile with the features I propose:

A lot of PHP extensions: bcmath, bz2, calendar, curl, exif (incl. jpeg*), ftp, gd (incl. freetype*, jpeg*, png*), gettext*, iconv, ldap, libxml, mbstring, mcrypt*, mhash*, mysql*, mysqli*, oci8*, openssl, pdo (including the drivers pdo_mysql, pdo_oci, pdo_sqlite), shmop, snmp, soap, wddx, xmlrpc, xsl, zip, zlib, dbase, sysvmsg/sysvsem/sysvshm

* extensions marked require additional libraries to be compiled/installed.

Other, built-in extensions: ctype, date, dom, filter, hash, json, pcre, posix, Reflection, session, SimpleXML, Sockets, SPL, SQLite, tokenizer, xml, xmlreader, xmlwriter

If the list does not include a certain extension you need, I either did not care enough about it (e.g. I have never used PostgreSQL) or I could not get it to compile.

MySQL

Since PHP 5.3.0 there are two ways to get MySQL support.

MySQL Native Driver mysqlnd

To use the new mysqlnd in PHP 5.3 just replace the corresponding lines in the PHP configure line by

--with-mysql=mysqlnd \
--with-mysqli=mysqlnd \
--with-pdo-mysql=mysqlnd

When using mysqlnd you do not need to compile or install the MySQL server or client libraries. So if you are using a separate database server and don’t need MySQL on your development machine this might be for you.

I have not tested it and I would advise against it. It is the first release and it’s bound to have bugs.

Compiling and installing MySQL yourself

MySQL 5.0 Downloads

Enter Hivelogic again. Dan Benjamin has written a great tutorial about that, too: See Installing MySQL on Mac OS X. (He has written about a lot of stuff, just not PHP.) There you will probably find some tips similar to the ones in this tutorial.

Apache web server

Download - The Apache HTTP Server Project

The Apache web server is a straight-forward compile with the right configure arguments.

Note: Apache will be installed in /usr/local/apache2. If you want to install it somewhere else you will have to adapt the PHP ./configure line to point to your apache dir.

curl -O http://apache.mirror.clusters.cc/httpd/httpd-2.2.13.tar.bz2
tar xjf httpd-2.2.13.tar.bz2 
cd httpd-2.2.13/
./configure \
  --prefix=/usr/local/apache2 \
  --enable-mods-shared=all \
  --enable-proxy=shared \
  --enable-proxy_http=shared \
  --enable-ssl=shared
make
sudo make install
cd ..

freetype

FreeType Downloads

A Free, High-Quality, and Portable Font Engine. This is needed for GD.

curl -O http://mirrors.zerg.biz/nongnu/freetype/freetype-2.3.9.tar.bz2
tar xjf freetype-2.3.9.tar.bz2
cd freetype-2.3.9/
./configure
make
sudo make install
cd ..

gettext

gettext download

GNU `gettext’ utilities are a set of tools that provides a framework to help other GNU packages produce multi-lingual messages

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

jpeg

jpeg download

JPEG image compression

curl -O http://www.ijg.org/files/jpegsrc.v7.tar.gz
tar xzf jpegsrc.v7.tar.gz
cd jpeg-7/
./configure --enable-shared
make
sudo make install
cd ..

Note: Some version before v7 might require you to execute these two lines for configure to work:

cp /usr/share/libtool/config.sub .
cp /usr/share/libtool/config.guess .

mcrypt

mcrypt download

MCrypt is a replacement for the old crypt() package and crypt(1) command, with extensions.

curl -O http://sunet.dl.sourceforge.net/project/mcrypt/Libmcrypt/2.5.8/libmcrypt-2.5.8.tar.bz2
tar xjf libmcrypt-2.5.8.tar.bz2
cd libmcrypt-2.5.8/
./configure
make
sudo make install
cd ..

libpng

libpng download

libpng is the official PNG reference library.

curl -O ftp://ftp.simplesystems.org/pub/libpng/png/src/libpng-1.2.38.tar.bz2
tar xjf libpng-1.2.38.tar.bz2
cd libpng-1.2.38/
./configure
make
sudo make install
cd ..

mhash

mhash download

Mhash is a free (under GNU Lesser GPL) library which provides a uniform interface to a large number of hash algorithms.

curl -O http://kent.dl.sourceforge.net/sourceforge/mhash/mhash-0.9.9.9.tar.bz2
tar xjf mhash-0.9.9.9.tar.bz2
cd mhash-0.9.9.9/
./configure --mandir=/usr/local/share/man/
make
sudo make install
cd ..

t1lib

Rasterizer library for Adobe Type 1 Fonts.

curl -O ftp://sunsite.unc.edu/pub/linux/libs/graphics/t1lib-5.1.2.tar.gz
tar xzf t1lib-5.1.2.tar.gz
cd t1lib-5.1.2/
./configure
make without_doc
sudo make install
cd ..

imap (c-client)

This is kind of nasty. First, you have to compile the IMAP c-client. You can get it here.

curl -O ftp://ftp.cac.washington.edu/mail/imap.tar.Z
tar xZf imap.tar.Z
cd imap-2007b/
make oxp

oxp is the identifier for modern Mac OS X system.

Note: There is no make install! This sucks. So I had a peek at the macports Portfile for cclient. Use the following commands to install c-client manually.

destroot=
prefix=/usr/local
worksrcpath=.
sudo install -m 755 -d ${destroot}${prefix}/include/c-client
cd c-client/
sudo install -m 644 c-client.h dummy.h env.h env_unix.h \
  fdstring.h flockcyg.h flocksim.h flstring.h fs.h ftl.h \
  imap4r1.h linkage.c linkage.h mail.h misc.h netmsg.h \
  newsrc.h nl.h nntp.h osdep.h pseudo.h rfc822.h smtp.h \
  sslio.h tcp.h tcp_unix.h unix.h utf8.h utf8aux.h \
${destroot}${prefix}/include/c-client
cd ..
sudo install -m 644 ${worksrcpath}/c-client/c-client.a \
  ${destroot}${prefix}/lib/libc-client4.a

To update the table of contents of archive libraries you should run the ranlib command. I did it like this.

Note: sudo -s gives a root shell, exit closes it afterwards.

sudo -s
cd /usr/local/lib
ranlib libc-client4.a
exit

Oracle instant client

Instant Client downloads for Mac OS X (Intel x86)

If you do not need Oracle support, just skip this section.

Finally the Oracle instantclient is also available for intel-powered Macs. You need to create an account with Oracle to be able to download it.

Download the “Instant Client Package - Basic”, unarchive it to and copy the unarchived directory to e.g. /usr/local/instantclient. Download “Instant Client Package - SDK”, unarchive it and copy the sdk directory so that it lies within /usr/local/instantclient). Also, you need to issue the following command inside the instantclient directory.

ln -s libclntsh.dylib.10.1 libclntsh.dylib
ln -s libclntsh.dylib libclntsh.so

This will create a non-version specific symbolic link for one of the libraries and is needed by the PHP configure command (thanks to Mark Shropshire. I had forgotten to document this step.) The second line will fix a bug in the configure script. PHP searches for a .so file but on Mac OSX those files are called .dylib.

Oracle needs some variables set up before you can call ./configure for PHP:

export NLS_LANG="American_America.UTF8"
export DYLD_LIBRARY_PATH="/usr/local/instantclient"

This should then be set system-wide, or at least in the shell you use to start Apache or PHP cli.

For Oracle/OCI8 Support in PHP just append

--with-oci8=instantclient,/usr/local/instantclient \
--with-pdo-oci=instantclient,/usr/local/instantclient,10.2.0.4

to the ./configure line below. If the make install step of PHP fails when setting up PEAR because it cannot find an Oracle library, this is because you did not set export DYLD_LIBRARY_PATH="/usr/local/instantclient" for root. Use sudo -s to get a root shell in that case, export the DYLD_LIBRARY_PATH and then make install.

PHP

PHP: Get Download

The most important options are the first two ./configure arguments. --prefix says where php will be installed, which is /usr/local/php5 in my case. --with-apxs2 tells the script, where to find Apache. If you changed that when compiling Apache or if you want to compile a php module for a different Apache version then change this argument accordingly. The same goes for the mysql configure options.

curl -O http://de2.php.net/distributions/php-5.3.0.tar.bz2
tar xjf php-5.3.0.tar.bz2
cd php-5.3.0/

./configure
  --prefix=/usr/local/php5 \
  --with-apxs2=/usr/local/apache2/bin/apxs \
  --with-bz2=/usr \
  --with-config-file-scan-dir=/usr/local/php5/php.d \
  --with-curl \
  --with-freetype-dir=/usr/local/php5 \
  --with-gd \
  --with-gettext \
  --with-iconv \
  --with-iconv-dir=/usr \
  --with-imap-ssl=/usr/local \
  --with-imap=/usr/local \
  --with-iodbc=shared,/usr \
  --with-jpeg-dir=/usr/local/php5 \
  --with-kerberos=/usr \
  --with-ldap \
  --with-libxml-dir=shared,/usr/local/php5 \
  --with-mcrypt \
  --with-mhash \
  --with-mysql=/usr/local/mysql \
  --with-mysqli=/usr/local/mysql/bin/mysql_config \
  --with-openssl=/usr \
  --with-pdo-mysql=/usr/local/mysql \
  --with-png-dir=/usr/local/php5 \
  --with-snmp=/usr \
  --with-t1lib=/usr/local/php5 \
  --with-xmlrpc \
  --with-xsl \
  --with-zlib-dir=/usr \
  --with-zlib=/usr \
  --enable-bcmath \
  --enable-calendar \
  --enable-cgi \
  --enable-exif \
  --enable-ftp \
  --enable-gd-native-ttf \
  --enable-mbstring \
  --enable-pcntl \
  --enable-shmop \
  --enable-soap \
  --enable-sockets \
  --enable-sqlite-utf8 \
  --enable-sysvmsg \
  --enable-sysvsem \
  --enable-sysvshm \
  --enable-wddx \
  --enable-zip

make
sudo make install

Note: To make sure everything works fine you should execute make test before sudo make install. This will take some time, though. Make sure to configure the tests for database extensions like mysql and oci8 before running make test. See e.g. ext/oci8/README and ext/mysql/test/connect.inc;

Note for PHP before 5.3.0:

This was my configure line for PHP 5.2.9.

./configure \
 '--prefix=/usr/local/php5' \
 '--enable-bcmath' \
 '--enable-calendar' \
 '--enable-cgi' \
 '--enable-dbase' \
 '--enable-exif' \
 '--enable-fastcgi' \
 '--enable-ftp' \
 '--enable-gd-native-ttf' \
 '--enable-mbstring' \
 '--enable-pcntl' \
 '--enable-shmop' \
 '--enable-soap' \
 '--enable-sockets' \
 '--enable-sqlite-utf8' \
 '--enable-sysvmsg' \
 '--enable-sysvsem' \
 '--enable-sysvshm' \
 '--enable-wddx' \
 '--enable-zip' \
 '--with-apxs2=/usr/local/apache2/bin/apxs' \
 '--with-bz2=/usr' \
 '--with-config-file-scan-dir=/usr/local/php5/php.d' \
 '--with-curl' \
 '--with-freetype-dir=/usr/local/php5' \
 '--with-gd' \
 '--with-gettext' \
 '--with-iconv' \
 '--with-iconv-dir=/usr' \
 '--with-imap-ssl=/usr/local'
 '--with-imap=/usr/local' \
 '--with-iodbc=shared,/usr' \
 '--with-jpeg-dir=/usr/local/php5' \
 '--with-kerberos=/usr' \
 '--with-ldap' \
 '--with-libxml-dir=shared,/usr/local/php5' \
 '--with-mcrypt' \
 '--with-mhash' \
 '--with-mysql=/usr/local/mysql' \
 '--with-mysqli=/usr/local/mysql/bin/mysql_config' \
 '--with-openssl=/usr' \
 '--with-pdo-mysql=/usr/local/mysql' \
 '--with-png-dir=/usr/local/php5' \
 '--with-snmp=/usr' \
 '--with-t1lib=/usr/local/php5' \
 '--with-xmlrpc' \
 '--with-xsl' \
 '--with-zlib-dir=/usr' \
 '--with-zlib=/usr'

Note for PHP before 5.2.7: The make install script does not automatically install the command line tools (at least in some cases). Use this command to install them:

sudo make install-cli

Note for PHP before 5.2.7: There is a bug in autoconf with Mac OS X Leopard. The configure script for PHP tries to determine the file extension for executable files and ends up with .dSym due to that bug. To fix that you can either edit the Makefile and change the value of EXEEXT or just rename the binary after make install.

Option 1: Editing the Makefile. Change this entry (around line 100)

EXEEXT = .dSYM

to read like

EXEEXT =

Option 2: Renaming the binary:

sudo mv /usr/local/php5/bin/php.dSym /usr/local/php5/bin/php

Further notes

Architecture

All this will compile as 32 bit for i386. Use the following flags when configuring to compile 4-way universal binaries. I have not tried it, though, so YMMV.

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 …

Credits

Thanks to Dan Benjamin and Marc Liyanage for inspiring me to this tutorial.

Dan Benjamin is best known for his Ruby/Rails compiling & installing tutorials on OS X.

Marc Liyanage compiled MySQL and PHP for OS X officially for years and even provided installers.

Feedback

Feedback is always welcome. You can send me a mail at soryu2@gmail.com.