Compiling 64-bit Apache/PHP on Mac OS X 10.5.6

Update: The below installation still works on Snow Leopard with PHP 5.3. You can use the latest and greatest of each library/project below and it will still work. However, there is one gotcha. There is a bug somewhere (PHP blames Apple and vice versa) when compiling PHP. To get around this, run the following on the command line before the ./configure string:

# export EXTRA_LIBS=-lresolv;

I will update this with a new tutorial once I compile everything with Clang.

Warning: This installation was not done on a virgin machine. Everything has been tested and works on my heavily hacked system.

Ok. We’re going to compile Apache with PHP on OSX 10.5.6. To make things interesting, we’re going to do a 64-bit install. If you don’t know if your machine is 64-bit or not, follow this rule: Core Duo == 32 bit, Core 2 Duo == 64 bit. I haven’t found a way to reliably display the chip architecture from the OS X command line, but on most GNU/Linux variants, you can use lshw. On the mac, you can try `uname -p`, `arch`, `system_profiler SPHardwareDataType` but all of this will make you think you are running 32 bit. As the man page for `arch` states:

The most common use is to select the 32-bit architecture on a 64-bit processor, even if a 64-bit architecture is available.

So everything is defaulted to 32-bit. What we need to do is set some environment variables so gcc knows the architecture we want to compile against. Another thing, I’m going to do all of this as root (back off unix weenies – I know what sudo is and use it regularly, I’m not here to argue about this). You can do this with the following (the # represents the prompt):

# MACOSX_DEPLOYMENT_TARGET=10.5
# CFLAGS="-arch x86_64 -g -Os -pipe -no-cpp-precomp"
# CCFLAGS="-arch x86_64 -g -Os -pipe"
# CXXFLAGS="-arch x86_64 -g -Os -pipe"
# LDFLAGS="-arch x86_64 -bind_at_load"
# export CFLAGS CXXFLAGS LDFLAGS CCFLAGS MACOSX_DEPLOYMENT_TARGET

I’m also going to ratchet up the complexity a bit because I need a GD library, IMAP, iconv, and OpenSSL. So here goes:

1) Grab All The Tarballs
Here are the links to the tarballs needed. Most of these you can grab with `curl -O` or `curl -O -L` to follow a redirect:

I’m not going full bore with the GD Library here, I just want to create some basic graphs, manipulate images, etc. so I’m not getting XBM or WBMP. I’m going to download all this stuff into /usr/local/src/.

2) Compile The GD Libraries
First we’ll start with the GD libraries as these are pretty straight forward and shouldn’t give you any problems. When on the `make` step of each of these libraries, you’ll see the familiar “-arch x86_64″, this means we’re doing it right.

FreeType

# tar -xzvf freetype-2.3.8.tar.gz
# cd freetype-2.3.8
# ./configure
# make
# make install

libjpeg

# tar -xzvf jpegsrc.v6b.tar.gz
# cd jpeg-6b
# ./configure
# make
# make install

libpng

# tar -xzvf libpng-1.2.34.tar.gz
# libpng-1.2.34
# ./configure
# make
# make install

t1lib
You will need to modify the “configure” file after you untar the file. So open “configure” and modify line 8656 to read:

archive_cmds='$CC -arch ppc -arch ppc64 -arch i386 -arch x86_64 -g -Os  -pipe -dynamiclib $allow_undefined_flag -o $lib $libobjs $deplibs $compiler_flags -install_name $rpath/$soname $verstring'

The architecture types must be explicitly stated for configure to work properly. There is an alternate method of modifying the resulting Makefile, but I won’t go into that. Commands are:

# tar -xzvf t1lib-5.1.2.tar.gz
# cd t1lib-5.1.2
# vi configure (make changes above)
# ./configure
# make without_doc
# make install

Some of these installs might give you lip about certain directories not being found. Make sure you have the following directories on your system:

/usr/local/include
/usr/local/bin
/usr/local/lib
/usr/local/man/man1

3) Compile OpenSSL
Since many components rely on this. We want to get it compiled and in place fairly early.

# tar -xzvf openssl-0.9.8j.tar.gz
# cd openssl-0.9.8j
# ./config --prefix=/usr/local/ssl
# make
# make install

4) Compile IMAP
This is pretty easy, but some extra steps need to be taken because make install doesn’t seem to exist:

# tar -xzvf imap.tar.gz
# cd imap-2007e
# make oxp
# mkdir /usr/local/imap
# cp -pr c-client /usr/local/imap/

5) Compile libicon
A very useful library that doesn’t seem to get much love. This will convert between character sets (UTF-8, etc.). Maybe dealing with Japanese characters for so long gave me this appreciation.

# tar -xzvf libiconv-1.12.tar.gz
# cd libiconv-1.12
# ./configure
# make
# make install

6) Compile Apache
This assumes you already have MySQL on your machine. The 64-bit package installer at http://dev.mysql.com/downloads/ should be all you need to install this. I would stick with 5.0.x even though 5.1 is GA (Monty of MySQL fame has some choice words about this). Even though I love compiling my own apps, MySQL does such a good job with their installer, I’ve left it to them for the past couple years.

# tar -xzvf httpd-2.2.11.tar.gz
# cd httpd-2.2.11
# './configure' '--prefix=/usr/local/apache2.2.11' '--with-included-apr' '--enable-module=most' '--enable-shared=max' '--enable-headers' '--enable-rewrite'
# make
# make install

A couple things to note:

  • You normally don’t have to explicitly state which apr to use, your system will figure this out. I had a version installed by darwin ports for subversion and the compiler wanted to use that one and would choke (this is Versions‘ fault).
  • You don’t need the enable-headers and enable-rewrite. I like to do funky things like mod_rewrite for pretty URLs and mod_proxy for Tomcat. Choice is yours.
  • From httpd-2.2.9, the configure options got all out of whack with slight syntax modifications to some important flags. To normalize this, you need to run `./buildconf` in the src directory before configuring. Seems like things are back to normal for 2.2.11.
  • In my config string, I spell out which version of the software I’m using – apache2.2.11 – then later symlink /usr/local/apache2 to /usr/local/apache2.2.11. This is useful for running multiple versions.

7) Compile PHP
The final step. Here is where you’ll be able to see if you’ve done everything above correctly.

# tar -xzvf php-5.2.8.tar.gz
# cd php-5.2.8
# './configure' '--prefix=/usr/local/php' '--with-apxs2=/usr/local/apache2.2.11/bin/apxs' '--with-zlib=/usr' '--with-mysql=/usr/local/mysql/' '--with-mysqli=/usr/local/mysql/bin/mysql_config' '--with-gd' '--with-png-dir=/usr/local/php' '--with-jpeg-dir=/usr/local/php' '--with-freetype-dir=/usr/local/php' '--with-t1lib=/usr/local/php' '--with-xmlrpc' '--with-pear' '--enable-mbstring' '--enable-cli' '--with-curl=/usr/local/' '--enable-soap' '--with-openssl=/usr/local/ssl/'
# make
# make install

Some things to note:

  • You may not need all these compile options. Pick and choose what you feel you need.
  • I compiled my own version of curl, but you can leave this out of the config string if you are ok with the default OSX curl. I’m a huge fan and power user of curl. Maybe someday I’ll write about what that means.

Other Configuration Stuff:

  • Change user/group to www:www in conf/httpd.conf
  • I’m not going to get into it too much, but make sure you compare your old httpd.conf file (/etc/apache2/httpd.conf) with the new one. There are several Apple specific directives in there to keep your webserver safe.
  • Make sure to add support for mod_php:

<IfModule mod_php5.c>
AddType application/x-httpd-php .php
AddType application/x-httpd-php-source .phps
</IfModule>

  • If you want this new version of Apache to start automatically at startup, make sure it is enabled in sharing, then do this:

# cd /usr/sbin/
# mv apachectl apachectl.bak
# ln -s /usr/local/apache2/bin/apachectl apachectl

Now fire up apache and load a page with <? phpinfo(); ?> to see that everything has installed correctly.

I’m more than happy to answer any questions you have about this process, so fire away!

Warning: This installation was not done on a virgin machine. Everything has been tested and works on my heavily hacked system.

Search Engines Scrubbing User Data

Post from iPhone:

In December, Yahoo announced they were going to reduce the length of time they retain user data to six months. Microsoft also jumped in and said they would do the same and urged Google to follow suit.

This is a pretty slimey, anticompetitive tactic disguised as “protecting user privacy”. See, one of Google’s main advantages is the data they can glean from user activity. Of course, Google can scramble the data as they offered to do in the YouTube lawsuit but that isn’t the point. Yahoo and MS are crippling themselves in an attempt to cripple Google. It is the same tactic used by retailers – “if you find a lower price, we’ll match it”. All this does is freeze any kind of price competition by eliminating any benefits of doing so.

This Yahoo gambit has been going on for a while, years in fact, but it just doesn’t seem to help. It draws privacy group attention and they always say it isn’t enough. Google either ignores them or scrambles the data. Usually if Google responds, it brings the attention of the privacy groups so you see less action on Google’s part.

New OS X Mail Behavior

Mail Delete Box

Mail Delete Box

This one caught me by surprise this morning as I was forwarding a message in OS X Mail. It seems if you have a threaded message (at least two levels deep) and you click within a nested level, a new delete marker comes up. Clicking the “x” on the upper left of the box will wipe out the nested threads. Never saw this before and have to say I’m pleasantly surprised.

The reason I’m blogging about this is to prove a small point. Whereas Windows seems to be out to get you, working against you at every step; OS X works with you and tries to help at every step. When asked why I use OS X, this is what I try to explain and this is just a small example of that in action.

A couple years ago I was talking to an executive in a fortune 500 company about this. The other day, I found out that I had converted him with this logic and he is now a die hard Mac fan.

Anyway, I have a couple big posts waiting in the wings that need a bit more research. Hopefully I’ll get one of those up today.

The Recent Google Knol Furor

Google KnolI’ve been sitting on this one for a while as I read countless reports on “Knol vs. Wikipedia”, “Why [Knol|Wikipedia] is dead”, “Knol has failed”, “Why Didn’t Google Kill Knol?”, etc.

I’m going to keep this one short as a) I see that a lot of people already have already come to conclusion I present below, b) I have a raging cold and want to get back to bed. Check out the comments on “Why Has Knol Survived Google’s Ophan-Killing Spree?“, btw I haven’t even read the article, just the comments.

So here is the deal with Knol:

1) Knol allows you to select New Yorker comics to insert into your Knol for free, WTF? If you are a Seinfeld fan, you’ll appreciate the comedy behing how cryptic these comics are. Well, it turns out Udi Manber is a huge fan. Who is Udi Manber? He is the Google’s VP of Engineering, Core Search.

2) Knol is Udi Manber’s 20%-time project. Udi Manber controls the levers operating Google’s empire, this is important stuff. What Manber wants, Manber gets so this project will never get killed (unless Udi kills it).

3) Udi Manber has a small little goal for Google – “human understanding and intent”. How is this done? Semantics and the semantic web. Manber has been involved in search for a long time and has published many papers and written many applications to harness the power of words/computing to make a better search experience.

4) So the point of Knol? Provide a corpus of structured knowledge to experiment with Manber’s search technologies.

So Knol is not about competing with Wikipedia, it is not about making money for authors or Google via adsense. Google couldn’t care less about these things, they (Manber) want to improve search. Once you can crack the “human intent” nut, search is yours for the taking.

image: Google

Bolting A Framework Onto WordPress

This took me about 10 minutes to figure out and implement. I’m surprised how easy it was. The first thing I did was create a new template and called it “dynamic”. Any wordpress page that wants to use the framework needs to be created with this template and the content left empty.

The dynamic template is then called and the $_SERVER['REDIRECT_URL'] is parsed and if the appropriate page resides within the framework, load it all up and serve the dynamic content. If not, throw some negativity at the user.

So the dynamic page acts as the entry point to the framework and passes off the directive in a switch type fashion. Pretty simple and works fine so far.

Has anyone else done something similar or is there a better way of creating dynamic pages? Am I being lame?