I’ve recently installed Apple’s new 64 bit OS Snow Leopard, on my work computer. I use postgresql extensivly together with python, and usually use apple’s bundled python2.5 for working with django.
As the daredevil I am, I wanted to recompile all my macports to use the new 64 bit system, and therefore deleted them all, and made a fresh install of macports. After building the postgresql81 port, I was about to build the psycopg2 python postgresql driver for python 2.5, when it gave me a warning about not being able to find some symbols in the postgresql library it had linked to. I quickly realized that this might be an architecture problem, and sure enough, it turns out that python 2.5 is a i386/ppc and python 2.6 is x86_64/i386/ppc binary, as can be seen here:
$ file `which python`
/usr/bin/python: Mach-O universal binary with 3 architectures
/usr/bin/python (for architecture x86_64): Mach-O 64-bit executable x86_64
/usr/bin/python (for architecture i386): Mach-O executable i386
/usr/bin/python (for architecture ppc7400): Mach-O executable ppc
$ file `which python2.5`
/usr/bin/python2.5: Mach-O universal binary with 2 architectures
/usr/bin/python2.5 (for architecture i386): Mach-O executable i386
/usr/bin/python2.5 (for architecture ppc7400): Mach-O executable ppc
The solution seemed so simple. Recompile postgresql81 for both architectures, and let the linker figure out the rest.
Building the postgresql81 port as the +universal variant, does not work. It has something to do with the fact, that the linker (ld) does not know how to produce a binary for multiple architectures. After a good nights sleep, the solution was only a trac ticket away.
So, to build a i386 and x86_64 version of postgresql8x via macports, you have to patch the Portfile, which is located in /opt/local/var/macports/sources/rsync.macports.org/release/ports/databases/postgresql81.
That can be done like this – notice that the patch seem to place the files wrong, so we’re moving them as well:
$ cd /opt/local/var/macports/sources/rsync.macports.org/release/ports/databases/postgresql81
$ curl -s http://trac.macports.org/raw-attachment/ticket/14619/combined_updated_universal.patch | sudo patch
$ sudo mkdir files/
$ sudo mv ld.sh files/
$ sudo mv patch_pg_config_h files/
Now you can go ahead and build the postgresql81 port with both architectures, like so:
$ sudo port install postgresql81 +universal
And then, finally, we can build the psycopg2 extension for python:
$ wget http://initd.org/pub/software/psycopg/psycopg2-2.0.12.tar.gz
$ tar zxf psycopg2-2.0.12.tar.gz
$ cd psycopg2-2.0.12
$ sudo python2.5 setup.py install
$ sudo python2.5 setup.py clean
$ sudo python2.6 setup.py install
And you’re off.