Looks like no one’s replied in a while. To start the conversation again, simply ask a new question.

Compiling a universal binary with GCC

How would I go about building a universal binary just using gcc from the terminal? Also, how can I make it so the resulting binary can be used on other computers than my own?

15 inch Powerbook G4, Mac OS X (10.5.2)

Posted on Feb 28, 2008 12:07 AM

Reply
Question marked as Best reply

Posted on Feb 28, 2008 9:43 AM

From the gcc man page:

-arch arch
Compile for the specified target architecture arch. The
allowable values are i386, ppc and ppc64. Multiple options
work, and direct the compiler to produce ``universal''
binaries including object code for each architecture specified
with -arch. This option only works if assembler and libraries
are available for each architecture specified. (APPLE ONLY)

HTH,
Gabriel.
3 replies
Question marked as Best reply

Feb 28, 2008 9:43 AM in response to lladnar

From the gcc man page:

-arch arch
Compile for the specified target architecture arch. The
allowable values are i386, ppc and ppc64. Multiple options
work, and direct the compiler to produce ``universal''
binaries including object code for each architecture specified
with -arch. This option only works if assembler and libraries
are available for each architecture specified. (APPLE ONLY)

HTH,
Gabriel.

Feb 28, 2008 11:14 AM in response to lladnar

This Makefile illustrates how to create an universal executable:


# Makefile
# Create universal executable
hello: hello.i386 hello.ppc
lipo -create -output hello hello.ppc hello.i386
# Create Intel executable
hello.i386: hello.c
gcc -arch i386 -o hello.i386 hello.c
# Create PPC executable
hello.ppc: hello.c
gcc -arch ppc -o hello.ppc hello.c


Let me know if you don't understand how it works. Note: if you copy and paste the text above, make sure you have a tab and not spaces before each command ( lipo and gcc).

The example file is simply:


/* hello.c */
#include <stdio.h>
int main(void)
{
printf("Hello world ");
return 0;
}


The file command can be used to verify that you have a universal binary:


$ file hello
hello: Mach-O universal binary with 2 architectures
hello (for architecture ppc7400): Mach-O executable ppc
hello (for architecture i386): Mach-O executable i386


Finally, if you have an Intel Mac, you can run the PPC version of hello under Rosetta as following:


$ /usr/libexec/oah/translate hello
Hello world

Feb 28, 2008 5:49 PM in response to lladnar

You have to add the following parameters to your compile and/or link step:

-isysroot /Developer/SDKs/MacOSX10.4u.sdk -arch i386 -mmacosx-version-min=10.4

This will build for 10.4 or later on Intel. If you are really sure that your code can compile with all the same settings regardless of architecture, you could add "-arch ppc" to build a universal binary. A safer alternative would be to do:

-isysroot /Developer/SDKs/MacOSX10.3.9.sdk -arch ppc -mmacosx-version-min=10.3

to give you a 10.3-compatible Universal Binary.

Finally, lipo the executables together with:

lipo -create <myapp>.ppc <myapp>.i386 -output <myapp>

assuming, of course, that you have instructed your build scripts to append the architecture onto the end of the executable name, as in this example.

To make sure your app can run on any machine, you could just link with static libraries. That might be difficult because most packages build dynamic libraries by default. What you can do is include your dynamic libraries with your application. MacOS X executables are actually folders with lots of files inside. Some of those files can be dynamic libraries. After you build your app, create a "Run Script" build phase to use the "install nametool" to tell the executable that its dynamic libraries are located inside its bundle. I have a more detailed write up if you want to try it.

Compiling a universal binary with GCC

Welcome to Apple Support Community
A forum where Apple customers help each other with their products. Get started with your Apple ID.