Building a static universal Postgresql

Most of the time when you are building Postgresql, you can probably just do a generic config with whatever options you want, and be fine. If you are just running the server on a given machine, you have no need for a static build or a universal binary- in fact, such things could be counter-productive for all I know. However, once in a while you do need a static universal build, at least of the libraries- such as when you are using them in your own application and you need it to run on any machine you drop it on. This is the situation I found myself in recently.

Now the normal procedure to build a static universal library is to give the architectures in question (in my case ppc7400, i386, and, for good measure,x86_64) to the CFLAGS and LDFLAGS environment variables, and (at least on postgress and most of the things I have compiled) the --static, --disable-shared, or similar flag to the configure script. Unfortunately, this didn’t work for me with Postgres.

The first problem I ran into was with the --disable-shared flag. for some reason, when attempting to build with this flag, it would complain about “No rule to make target `libpq.5.3.dylib', needed by `all-shared-lib'”. Why it is trying to make all-shared-lib when I specifically requested that shared libs be disabled, I don’t know. However, the solution turned out to be run the build twice. First configure and make for a standard shared library install (no --disable-shared flag). Then, immediately after the make completes, but without running a clean or install, re-run configure with the --disable-shared flag. You can then make and install the static libraries with no further complaints about the missing shared make target, but still end up with static libraries only.

The second problem I ran into was that when I attempted to specify multiple -arch flags for CFLAGS and LDFLAGS, the build would invariably fail. While I don’t know the exact cause of the problem, the solution turned out to be to build for each architecture separately, and then use lipo to combine the resulting library. Keep in mind that you still have to run each build twice to work around the --disable-shared problem, so for the three architectures I mentioned above, you actually have to run configure and make six times before you end up with a functional, universal and static build of the postgres libraries. Whew. I whipped up a small script to make it easier on myself. The script doesn’t include the lipo commands, but essentially you just have to run “lipo --create <ppc source lib> <i386 source lib> <...> --output <destination lib>” for each library in the pgsql/lib directory. A simple for loop should be able to handle this nicely :-)

The end result should be a fully static, three-way universal build of the Postgresql libraries, ready to be linked into your program and run on just about any machine it is stuck on, be it Intel or PPC. Good luck!

© Israel Brewster 2011-2016