Building Postgresql on OS X

If you're just looking to install Postgresql on OS X, this probably isn't what you're looking for. Instead, take a look at the one click installer here.

If, though, you're looking to build Postgresql from source on OS X, read on.

It isn't trivial to build Postgresql from source on OS X in a way that gives "fat" libpq.dylib that supports both i386 and x86_64 build. This is needed not only for building fat binaries, but also for building fat libraries (such as Qt) that depend on libpq. This set of instructions will hopefully make it easier.

Many applications will build fat binaries on OS X fairly simply, just by adding "-arch i386 -arch x86_64" to the compiler and linker commandlines, usually by setting CFLAGS, CXXFLAGS and LDFLAGS before running configure. This doesn't work for Postgresql, for several different reasons. Instead we need to build Postgresql once for each architecture we support, then stitch the different libraries together with lipo.

We're going to build an installation where the server and client binaries are build for x86_64, but the libpq library is built as a fat binary supporting both i386 and x86_64. You should be able to extend it to support PPC code if you need that. We're installing everything in /usr/local/pgsql84.

Readline

The version of readline bundled with OS X has bugs that cause psql to abort during tab completion an annoying fraction of the time. So, while we don't have to install our own copy of readline, we're going to.

Download the readine tarball as linked from here. Right now that's readline-6.2.tar.gz.

Build and install it:

% tar zxvf readline-6.2.tar.gz
% cd readline-6.2
% CFLAGS="-arch i386 -arch x86_64" LDFLAGS=="-arch i386 -arch x86_64" ./configure
% make -j8
% sudo make install

Build Postgresql

Download the Postgresql tarball from here. I want to install a slightly older version, 8.4.7, as I'm using it to develop software that may need to run on 8.4 and later, but you'll probably want to get the latest version (9.something).

Untar the source:

% tar xjvf postgresql-8.4.7.tar.bz2
% cd postgresql-8.4.7

Build and install for x86_64:

% CFLAGS='-arch x86_64' LDFLAGS='-arch x86_64'  ./configure --prefix=/usr/local/pgsql84 --with-openssl --with-libs=/usr/local/lib --with-includes=/usr/local/include
% make -j8
% sudo make install

You may want different configure flags - see "./configure --help" for a list of them.

Next, build and install for i386:

% make distclean
% CFLAGS='-arch i386' LDFLAGS='-arch i386'  ./configure --prefix=/usr/local/pgsql84-i386 --with-openssl --with-libs=/usr/local/lib --with-includes=/usr/local/include
% make -j8
% sudo make install

Bodge the libraries together with lipo:

% cd /usr/local/pgsql84/lib
% sudo mkdir original
% sudo mv libpq.a libpq.5.2.dylib libpqtypes.a libpqtypes.3.1.dylib original
% sudo lipo -create ../../pgsql84-i386/libpq.a original/libpq.a -output libpq.a
% sudo lipo -create ../../pgsql84-i386/libpq.5.2.dylib original/libpq.5.2.dylib -output libpq.5.2.dylib
% sudo lipo -create ../../pgsql84-i386/libpqtypes.a original/libpqtypes.a -output libpqtypes.a
% sudo lipo -create ../../pgsql84-i386/libpqtypes.3.1.dylib original/libpqtypes.3.1.dylib -output libpqtypes.3.1.dylib

You'll need to choose the right filenames for the .dylib files - you want to lipo together the real files, and leave the symlinks untouched.

At this point postgresql is built. You can delete the /usr/local/pgsql84-i386 temporary installation once you're sure everything is right.

Install the database

This works pretty much like installing postgresql on any other platform, but creating the postgres user to own the database is a little trickier than on other unixes.

Create the postgres user:

% sudo dscl . -create /Users/postgres
% sudo dscl . -create /Users/postgres UserShell /bin/bash
% sudo dscl . -create /Users/postgres RealName Postgresql
% sudo dscl . -create /Users/postgres UniqueID `dscl . -list /Users UniqueID | awk '{print $2 + 1}' | sort -n | tail -1`
% sudo dscl . -create /Users/postgres NFSHomeDirectory /usr/local/pgsql84

(The incantation in the fourth line is finding the next available userid to assign to the postgres user)

Create the database cluster and start the server:

% sudo -u postgres /usr/local/pgsql84/bin/initdb -D /usr/local/pgsql84/data
% sudo -u postgres /usr/local/pgsql84/bin/pg_ctl -D /usr/local/pgsql84/data start

By this point the server should be running, and you can add /usr/local/pgsql84/bin to your path, create a database and be ready to go.

What we didn't mention

This set of instructions are for setting up a development box, where the database is started and stopped manually. For production use you'd want postgresql to be started when the server is booted and stopped when it's shut down. For that you'd likely want a launchd script - I've never gotten that to work well, but I gather the EnterpriseDB single-click installer has a good example of that.