Building G3 Code on Leopard

Introduction

If you try to build ppc code on Leopard, it will be compiled for the G4 and better instead of for the G3. This is fine for any code that runs on Leopard since Leopard's minimum requirements is a G4. But if you're building code on Leopard that is to be run on Mac OS X 10.4 Tiger, then your G3 Tiger users will be screwed.

The Proof

Look what happens when I try to build some code and then look at the result.

First, use gcc to build some code.

[jvink2:~/Development/Tests] jav% gcc -arch ppc -c -o foo.o foo.c

There. You see how I said "ppc", right? Now look at the result from lipo:

[jvink2:~/Development/Tests] jav% lipo -info foo.o
Non-fat file: foo.o is architecture: ppc7400

ppc7400 means G4. ppc970 means G5. Just ppc means G3. So this code is built for G4 and better.

Launching this code on a G3 might result in a dyld error like:

dyld: Library not loaded: @executable_path/../Frameworks/Bad.framework/Versions/A/Bad
  Referenced from: /Users/apple/Desktop/1.0b4/BadTest
  Reason: no suitable image found.  Did find:
        /Users/apple/Desktop/1.0b4/Bad.framework/Versions/A/Bad: no matching architecture in universal wrapper
Trace/BPT trap

The Solution

The compiler knows that if you're building for PowerPC for Tiger then it needs to generate code that works on the G3. To tell the compiler this, we just add the min macosx flag:

[jvink2:~/Development/Tests] jav% gcc -arch ppc -mmacosx-version-min=10.4 -c -o foo.o foo.c

Now the result will run on G3 machines:

[jvink2:~/Development/Tests] jav% lipo -info foo.o
Non-fat file: foo.o is architecture: ppc

If you're using Xcode, then setting the Mac OS X Deployment Target to 10.4 or earlier should do this for you.

Still not working?

If you build your project, and the result is still ppc7400, maybe one of the static libraries you're linking with is still ppc7400. Make sure those are all built for ppc.

Check that all your object files are ppc.

[jvink2:~/Development/Build] jav% find . -name \*.o -exec lipo -info {} \;

These are not:

Non-fat file: ./IconComposer.build/Development/Icon Compositor.build/Objects-normal/ppc/ApplicationSoftwareUpdate.o is architecture: ppc7400
Non-fat file: ./IconComposer.build/Development/Icon Compositor.build/Objects-normal/ppc/BitmapUtilities.o is architecture: ppc7400
Non-fat file: ./IconComposer.build/Development/Icon Compositor.build/Objects-normal/ppc/ColourTable.o is architecture: ppc7400
Non-fat file: ./IconComposer.build/Development/Icon Compositor.build/Objects-normal/ppc/FatIconView.o is architecture: ppc7400
Non-fat file: ./IconComposer.build/Development/Icon Compositor.build/Objects-normal/ppc/icoDataMaker.o is architecture: ppc7400
Non-fat file: ./IconComposer.build/Development/Icon Compositor.build/Objects-normal/ppc/IconSegmentedControl.o is architecture: ppc7400
Non-fat file: ./IconComposer.build/Development/Icon Compositor.build/Objects-normal/ppc/ImageDump.o is architecture: ppc7400
Non-fat file: ./IconComposer.build/Development/Icon Compositor.build/Objects-normal/ppc/main.o is architecture: ppc7400

Extreme Mac OS X Programming. Copyright 2009 John A. Vink