Introduction
If you’ve used PHP for development on OS X long enough, you’ve probably run into a few headaches (especially if your on a 64-bit system). Maybe it was trying to enable GD support or use Xdebug, but at some point things went crazy. There are many articles online dealing with fixes to individual issues (like activating GD), but often they’re conflicting and the writer doesn’t fully explain the mechanics of what’s being suggesting. Usually, this isn’t too much of a problem as you’ll eventually find a combination of articles or post that gets up and running and for you to get back to coding PHP. All is good…
…until you move to another framework or need a specific library and you find you need something else plugged into PHP. Once again you search for the magic combination of sites that allow you to jury-rig your PHP-Apache environment to get things moving. Happily you resume work, then remember you had to do something on an earlier project. Crisis! Now the prior project is freaking out because you’re now missing libraries that were removed or changed when you applied the latest PHP fix and no matter how hard you try you can’t get everything working together.
Ok, everybody, go to you window, open it up and repeat after me: I’M MAD AS HELL AND I’M NOT GOING TO TAKE IT ANY MORE.
Now calm down and continue reading. This article is part 1 of a multi part series going to go through a step-by-step process for getting an iron-clad PHP environment on your OS X Leopard system. The best part is each step will be explained thoroughly (and some links to other pages with deeper information) to allow you to understand what the heck is going on. This is important as I cannot guarantee you’ll not encounter problems (especially as with each new release of PHP and OS X things will change) , but with proper knowledge you can at least isolate what is screwing up and stand a chance of making your own way.
Prepare your Development Environment
Before we get started, there are several things you must be aware of:
- You’re Running OS X Leopard 10.5.x (other versions may work)
- You’re looking to install PHP 5.2.9 or higher
- You’ll need superuser (root login or sudo) priviliges
- You’ve not altered the Apache Web server installed by Leopard (if you’ve installed another version, you probably know enough to substitute it’s details in where needed)
- You know what a terminal is and how to bring one up
- You’re comfortable navigating around in a terminal, creating dirctories, moving them around, and have some familiarity editing files.
If you’ve answered no to any of these, you may need to adapt this article or read a book on basic Unix usage.
Now the biggest stumbling blocks is that we may encounter is that many PHP programmers aren’t C programmers. As PHP, Apache, MySQL, and the majority of libraries are built in C, using enormous make files and esoteric compiler commands. Our goal here is not to teach C, but to give you a rough idea of what’s going on as we’re going to be building (almost) everything from raw sources files. Almost all source code will be primarily in C, but thankfully you won’t have to touch any of that mess–only the occasional Makefile.
For this to work you’ll need a C compiler and set of common development applications and libraries. The most common and possibly the most powerful example of free, open source code on the planet is the Free Software Foundation’s GCC Compiler Collection. This is what we’ll be using. On OS X, there are a number of ways to obtain and setup GCC, but by far the easiest way is to install Apples Xcode. A copy of Xcode is on the OS X installation disks for OS X Leopard or you can download the latest version at http://developer.apple.com/technology/Xcode.html
This step may take a while–especially if you have to download it from Apple–so get started. While it’s downloading and installing lets get familiar with your system.
Getting to know your system
OS X makes it pretty difficult to find out one key detail regarding your system: whether it’s 32-bit or 64-bit. Open a terminal and try each of the the following:
$ arch$ uname -p
Both will report back i386. There is a good chance this is an outright lie. Open up the System Profiler by going to the Apple Menue->About This Mac, then select “more info”. You’ll get a lot of great information, but nothing as obvious as Intel 64 bit… You could infer from the Processor Name whether your system is 32 or 64 bit. Basically, if you happen to be an encyclopedia of processor knowledge you might be able to assertain that a ‘Intel Core Duo’ is 32-bit, while a ‘Intel Core 2 Duo’ is a 64-bit system. Clear as mud, eh? It would be better if we had some real proof.
Let’s investigate a file on the system. We’lllook at the Apache Web Server application (the
binary). Type the following:
$ file /usr/sbin/httpd
Note: If you’ve installed a new version this might not match exactly. You should see:
/usr/sbin/httpd: Mach-O universal binary with 4 architectures<br />/usr/sbin/httpd (for architecture ppc7400): Mach-O executable ppc<br />/usr/sbin/httpd (for architecture ppc64): Mach-O 64-bit executable ppc64<br />/usr/sbin/httpd (for architecture i386): Mach-O executable i386<br />/usr/sbin/httpd (for architecture x86_64): Mach-O 64-bit executable x86_64
The file command takes as an argument a file name, then prints out all sorts of useful information. From this run we know that
is a binary and has been compiled to support several different architectures. All (I think) of the programs Apple distributes with OS X are compiled to run on any architecture they support. This is what Apple refers to as Universal Binaries. Basically, they compile their files with setting for the compiler that builds the code each architecture and then binds them together in one binary file. It results in larger files, but not as large as you think–especially when your dealing with libraries only a few megabytes in size. When run, the system uses the correct code for the architecture the system is running so they only eat up about the same memory that would be used for the same binary compiled for just a specific architecure.
The architecture identifiers (ppc, ppc64, i386, and x86_64) are the shorthand names you’ll need to use to your system when we start compiling source code. Not all binaries will have compilations for the 64-bit Intel (x86_64) or PowerPC (ppc64); they may only specify i386 and ppc. Try calling the file command on something else like the less command:
$ file /usr/bin/less
You’ll see it’s only compiled as 32 bit. Why? Because of a few reasons:
- It’s not a library that can be compiled with or linked to another application.
- There’s no need for less to use more than 4GB of memory.
- Less does not perform any significant calculations
For most things, this is fine even if you have a 64-bit system because:
On PowerPC and Intel Based Macs, 32 bit binaries will run on a 64 bit machine of the same processor type (i.e. 32-bit PowerPC binaries will run on a 64-bit PowerPC system and 32-bit Intel binaries will run on a 64-bit Intel system).
However, the converse is not true, 64-bit code, will not run a 32 bit machine regardless of architecture. If you take a look at some of the libraries in /usr/lib you’ll see most compiled for both 32-bit and 64-bit, regardless of the purpose of the library.
Why not just make life easy and compile everything for 32-bit? Well, presently, most things are. But as noted above anytime you could be dealing with memory intensive programs that try to use more than 4GB of RAM or do heavy calculations with very big or very small numbers, you’ll want to go with 64-bit if your system can support it. This is the reason why OS X ships Apache to run in 64-bit if on a 64-bit system, ever see what happens to memory on a system that gets Slashdotted? Say each Apache process (a instance of httpd) with PHP on the page runs at 15MB. If you get 300 similtaneous connections (and your configured to spawn that many), you’ve now got over your 4G limit.
Is this also the case for the shared libraries (more on share libraries later)? For example take the CUPs libraries (libraries for dealing with the CUPs print server):
$ file /usr/lib/libcups.dylib
The result is:
usr/lib/libcups.dylib: Mach-O universal binary with 4 architectures
/usr/lib/libcups.dylib (for architecture ppc7400): Mach-O dynamically linked shared library ppc
/usr/lib/libcups.dylib (for architecture ppc64): Mach-O 64-bit dynamically linked shared library ppc64
/usr/lib/libcups.dylib (for architecture i386): Mach-O dynamically linked shared library i386
/usr/lib/libcups.dylib (for architecture x86_64): Mach-O 64-bit dynamically linked shared library x86_64
Why does a library that provides interfaces to a print server utilities need to support 64-bit? I don’t know this particular library in detail, but it’s safe to assume it doesn’t internally need 64-bit support. I’ll let you think about this until the next installment of this article series,
So, getting back to our investigation, if you have a Mac, you’ll be either a PowerPC or Intel chip, running 32-bit or 64-bit. Now try quering the
application to see what version it is:
$ /usr/sbin/httpd -V
The first few lines should be something like:
Server version: Apache/2.2.11 (Unix)<br />Server built: Feb 3 2009 01:54:45<br />Server's Module Magic Number: 20051115:21<br />Server loaded: APR 1.2.7, APR-Util 1.2.7<br />Compiled using: APR 1.2.7, APR-Util 1.2.7<br />Architecture: 64-bit<br /><br />
This whether you’re running on a 32 or 64 bit system–httpd will run as 64-bit architecture if it can (remember, httpd was compiled as a Universal Binary). Now you know whether you’re Intel or PowerPC (from the System Profiler information) and whether it’s 32 or 64 bit. Write it down or commit it to memory as you’ll need it for later.
That’s all for this part. Check out Part 2!
