make a universal binary on OSX 10.6 – Snow Leopard

125244997_6af3d42e86_z

This post describes how to create a “fat binary” on Mac OS X. If you’re using Snow Leopard, I don’t know why you’d want to make one of these, except maybe to compile for distribution to an older OS version (Leopard) or something. In fact, I can’t even remember why I wrote this, but I wrote it some time last fall or winter and thought I’d go ahead and post it now since I’d already spent some time working on it.

It’s not hard to create a universal binary on Mac OS X – these instructions are for Snow Leopard, but probably work on Leopard too.

First, the code must be compiled for each architecture (i386, ppc and x86_64). Each compilation will result in a separate executable (binary) file.

Then use lipo to merge them into a universal binary.

Here’s a sample makefile that will do all of that at once for a command-line utility I wrote in C called “whead”.

CC=gcc
CFLAGS=
LDFLAGS=

all: i386 ppc x86_64 univ

i386:
$(CC) -o whead_$@ whead.c $(CFLAGS) $(LDFLAGS) -arch i386

ppc:
$(CC) -o whead_$@ whead.c $(CFLAGS) $(LDFLAGS) -arch ppc

x86_64:
$(CC) -o whead_$@ whead.c $(CFLAGS) $(LDFLAGS) -arch x86_64

univ: i386 ppc x86_64
lipo -create whead_i386 whead_ppc whead_x86_64 -output whead

clean:
rm whead_ppc whead_i386 whead_x86_64 whead

Just run the makefile:

[ngmarle@lorien whead.univeral]$ make
gcc -o whead_i386 whead.c -arch i386
gcc -o whead_ppc whead.c -arch ppc
gcc -o whead_x86_64 whead.c -arch x86_64
lipo -create whead_i386 whead_ppc whead_x86_64 -output whead

And ensure that the resulting binary is compatible with all architectures previously specified:


[ngmarle@lorien whead.univeral]$ file ./whead
./whead: Mach-O universal binary with 3 architectures
./whead (for architecture i386): Mach-O executable i386
./whead (for architecture ppc7400): Mach-O executable ppc
./whead (for architecture x86_64): Mach-O 64-bit executable x86_64
[ngmarle@lorien whead.univeral]$ ./whead
usage: ./whead hostname [port]

That’s it.

photo credit