How do I build Universal binaries (ppc/i386) using Xcode 3.2.2 for OSX? - xcode

I am trying to build a universal binary for a project at work, but I can't seem to get Xcode set up properly to do so.
I am familiar with the Apple Documentation regarding this, but apparently I am not reading it correctly.
The Xcode build options in question seem to be:
Architectures
Base SDK
C/C++ Compiler Version
Mac OS X Deployment Target
In my settings I have the following Valid Architectures: i386 ppc ppc64 ppc7400 ppc970 x86_64.
If I use the following options, I get a binary with i386 and ppc970:
Architectures: i386 ppc
Base SDK: Mac OS X 10.5
C/C++ Compiler Version: GCC 4.0
Mac OS X Deployment Target: Mac OS X 10.5
I have several questions about this:
Why ppc970 and not ppc7400 (or simply ppc)?
What is the difference between the ppcs (ppc, ppc64, ppc7400, ppc970)?
How do I get a binary for any ppc?
Apparently, I need a binary with ppc7400 to work on the Mac Mini we have for testing. The Mini has a G4 and is running OSX 10.5.8. From what I can tell, a binary with ppc7400 works but not one with only ppc970.
I have tried several combinations of the above build options, including changing my Base SDK to 10.4u. The above configuration is the only one that even builds. Other builds fail, often because of not recognizing header files or clearly available #defines. For example, if I change my compiler to gcc 4.2, I get errors searching for stdarg.h because of the #include_next directive and no clear path to correct headers. If I drop my Base SDK to 4.0, #define FSIZE long long is no longer recognized despite not changing any includes.
I'd really appreciate any insight you can give me on this.
EDIT UPDATE
Thanks for the info. I understand the flags now. But I get a strange result.
These are my build flags now:
GCC_VERSION = 4.0
MACOSX_DEPLOYMENT_TARGET = 10.4
SDKROOT = macosx10.5
GCC_MODEL_TUNING = G3
This produces object file (.o) that have arch 'ppc' as shown by lipo. All the included libs and frameworks are either 'ppc' or 'ppc7400' (again as shown by lipo). But, the final build is 'ppc970'.
I have gone over this very carefully to ensure I got everything. Can anyone think of a reason for the ppc architecture differences?
I've even gone so far as to create a new project (Hello World) and link it to all the libs and frameworks of the first project. Hello builds as 'ppc' not 'ppc970'.
This just makes no sense to me.

ppc970 == G5. If you need to support as far back as the G4 then just build for ppc7400.
Rather than messing with individual architecture settings, though, you can just select 32-bit Universal (or Standard (32/64-bit Universal), if appropriate) from the popup menu, and that should give you what you need.

In target settings make below changes..
GCC_MODEL_PPC64 = NO
i.e., uncheck “Use 64-bit integer Math”.
Enabling will turn on 64 bit. So it will be G5 onwards..

Related

Cross compile for iPhone on a mac?

How would I go about setting everything up to cross compile from my OSX 10.7 Macbook pro to my jailbroken 4th generation iPod touch. I'm mainly aiming to be able to port open source libraries to iphone. I can't seem to find any good/recent articles on cross compiling for iOS 4.
After some attempt, I found out that it's possible to use ./configure and force it to build for arm-apple-darwin11. You have to use these flags directly after the ./configure --some-flags:
CPP="cpp" CXXCPP="cpp"
CXX="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-llvm-g++-4.2" CXXFLAGS="-O -arch armv6 -arch armv7 -isysroot $SDK_ROOT/SDKs/iPhoneOS5.0.sdk"
CC="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/arm-apple-darwin10-llvm-gcc-4.2" CFLAGS="-O -arch armv6 -arch armv7 -isysroot $SDK_ROOT/SDKs/iPhoneOS5.0.sdk"
AR="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ar"
AS="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/as"
LD="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ld"
LDFLAGS="-lstdc++ -arch armv6 -arch armv7 -isysroot $SDK_ROOT/SDKs/iPhoneOS5.0.sdk"
LIBTOOL="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/libtool"
STRIP="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/strip"
RANLIB="/Developer/Platforms/iPhoneOS.platform/Developer/usr/bin/ranlib"
CPP and CXXCPP are the preprocessor required (the default one); CC and CXX are the path to the c and c++ compiler for arm that comes with Xcode, the other are flags the compiler gets or macros that defines the path to the most common tools used when compiling. I cannot grant everything will work, but this is a good idea of what you should do.
I'd suggest to add to ./configure these flags:
--prefix=/tmp/build --host=arm-apple-darwin11
what they do is to help create a makefile that will send libs and programs in a folder under /tmp/build.
Neither did I. All the toolchain I tried ended up in not working or creating x86_64 binaries, which won't work on iOS.
I'm currently trying to build apr directly on my iPad as I have installed from Cydia all the required things, yet I'm stuck kqueue.c not compiling properly. I have already ported lua and some other software, so I can say it generally works this way. The main reason for building on a native platform rather than cross compiling is that some programs rely on other programs (example: apr-util on apr) so some of them must be run. However, it's not possible to run arm on intel (at least without emulation, and iPhone Simulator uses i386 binaries).
Anyone who's interested in using/building UNIX tools on iOS has to keep these points in mind:
You might find what you wanted, but it's not said it'll work as expected (this is intended especially for developers. Example: apr is shipped in Cydia, but it's not a complete package, so it's useless to build apr-util).
You have to use a jailbroken device. This may become a problem if you break the OS and need to restore. Be always sure to save SHSH so that you're able to restore to a jailbreakable iOS.
If you don't find what you were searching, things will get pretty messy. Most software, although thought to work on generic UNIX system, might have problems on iOS, which is near OS X in structure and way to work, but has differences especially under the net-related sections.
Plus you'll probably have to (fake)code sign any software you build.
Even software without build problems may hold unwanted surprises: I had successfully build apache2 for iOS, but when I run I got stuck with SIGSYS, without much more explanation.
So, beware and brace yourself, because things are not easy usually.
About the fact of Mac being without a toolchain (except the one provided by Apple), this may hold an explanation as you don't need to have a mac to download Xcode, while a mac cost usually more than devs are willing to spend. This means there aren't much people doing the same thing you do, despite the boom mac hardware has had recently. Toolchains have been more or less successfully built for Linux based OSes, such as Ubuntu. You can always try to use a VM.

how do I build a universal binary with xcode 3.2.6?

I am using XCode 3.2.6 on an Intel Mac running OS X 10.6, to build a fairly simple app that needs to be able to run under OS 10.4 on a PPC-based Mac, in addition to modern Intel-based Macs.
Under the project settings, I only see options for 32-bit Intel, 64-bit Intel, and Standard (32/64 Intel). Should I be seeing a "Universal Binary" entry here?
I don't have any problem running it under 10.4 on an Intel Mac. I was careful not to use features that don't work under 10.4, and I think I set the project settings correctly to allow it to be backward-compatible to 10.4. It's just that I can't figure out how to get it to compile for PPC.
I'm flailing around, trying to figure out how to build a universal binary, and I think I'm probably just missing something obvious. Any help would be greatly appreciated.
You don't have to choose one of the predefined settings for the Architectures build setting. You can choose "Other..." and then explicitly enter a list of architectures like ppc, i386, x86_64.
By the way, there are extra tricks if you need to run on G3s: You must use GCC 4.0 and the 10.4 SDK.

what does macosx-version-min imply?

When I pass compiler flag -mmacosx-version-min=10.5, what does it mean? I think it implies the result binary is x86, not ppc, but is it 32 bits or 64 bits? I'm compiling on snow leopard, so default output binary is 64 bits. I'm not passing -universal, it's not 32bit-64bit universal binary, I think.
This option will be used by the various availability macros placed into the headers. This means that you can require a minimum version of OS, even if you have a more recent SDK (i.e. target 10.5 with a 10.6 SDK). Using a 10.6 API while targetting 10.5 will trigger a warning and the API will be linked with a weak_import attribute.
Most Apple's API headers contains availability macros for each class, methods, functions or enumerations in order to declare for each of them:
The minimum OS supported
The deprecation
The unavailability
...
The macros look like:
AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER
AVAILABLE_MAC_OS_X_VERSION_10_2_AND_LATER_BUT_DEPRECATED
...
As for the architecture, it only depends on the available architectures in the binaries of the SDK. For example with a 10.5 SDK, you can target four architectures (Intel/32bits, PowerPC/32bits, Intel/64bits, PowerPC 64bits), while with a 10.6 SDK, you can only target three architecture (Intel/32bits, PowerPC/32bits, Intel/64bits).
As you are using Snow Leopard, you can either target i386 (Intel/32bits), ppc (PowerPC/32bits) or x86_64 (Intel/64bits) very simply by passing an architecture option like this:
gcc -arch i386
or like this (for configure-based projects):
CFLAGS="-arch i386" LDFLAGS="-arch i386" ./configure
-mmacosx-version-min=... also influences the default choice of C++ STL implementation (GNU or LLVM), and in this regard, it is equally important for the compiler and the linker.
From my testing, it's also important that this option be passed to the link step (like -arch); so it does more than affect macros/preprocessing (as might be inferred from other answers).
When passed to compile step but not passed to the link step, I found that shared libraries built with 10.6 would not load under 10.5.
It triggers compiler warnings for methods that appeared after Mac OS X 10.5. Is has nothing to do with architecture.

Compiling for both Intel and PPC CPUs on OSX

I have a MacBook Pro with a 64-bit Intel Core 2 Duo processor, and I'm using gcc (i686-apple-darwin9-gcc-4.0.1) to compile executables which I can run ok on my own machine. Recently someone tried to run my application on a PowerBook G4 and got a 'Bad CPU type in executable' error, which I think is because their CPU is PPC rather than Intel (and also possibly 32 bit not 64 bit)
Is it possible for me to produce binaries that will work across all the various Mac architectures using gcc, and if so what options do I use?
Look at the -arch parameter for gcc Apple docs
You need to look into "Universal Binaries" this is the name given to an app file which runs, with no dynamic recompilation, on both ppc and i386 architectures. As you know .app files (Mac Executables), are in fact archives, which contain, within them, the actual binary application. These can be partitioned in such a way that both the i386 and ppc binaries are contained.
To save yourself and your users future headaches, you should bite the bullet and set up your project in Apple's Xcode. If you follow the defaults, Xcode can take care of all the details of building for multiple architectures, like using the proper -arch flags for gcc, using the correct SDK libraries, compatibility with previous OS X versions, etc etc.

ICL, OS X.4/5 and Unix compliance ($UNIX2003)

I'm trying to compile a Mac version of our lib for a customer that wants to include it in a Photoshop plugin, and he is having trouble linking our lib into his app. More detailed info: His plugin is built against the CS4 Photoshop SDK, which means the Mac OS base SDK should be 10.4. My lib is a static one, compiled with the Intel compiler 11.1 and the base SDK is also set as 10.4.
I tested my lib against a small test app I wrote, and it compiles and works fine (on 10.5). To replicate my customer's environment, the app is compiled with gcc, and uses the 10.4 base SDK. While its fine for me, my customer cannot manage to link with my lib. The problem is the following: Undefined symbols:
"_fputs$UNIX2003", referenced from:
_write_message in libMyLib.a(libm_error.o)
When I compile my lib with gcc,and all other project settings the same, its fine, he can generate an executable. As soon as I compile with ICL, it breaks down. Could it be that ICL 11.1 is not compatible with 10.4? On the Fortran compiler forum, I found the following answer:"From the output provided it appears Xcode defaulted to Mac OS X 10.4, which the 11.1 compilers do not support." (http://software.intel.com/en-us/forums/intel-fortran-compiler-for-linux-and-mac-os-x/topic/68647/)
Does that mean ICL 11.1 does not run on 10.4, or that the code it generates doesn't work on 10.4??
On the following page (http://software.intel.com/en-us/articles/performance-tools-for-software-developers-compatibility-of-intel-compiler-for-mac-os-x-and-xcode/), it also says that ICL 11.1 is not compatible with 10.4 (again same question: what does compatibility mean?). However, it says that ICL 10.1 is, so I tried. But now, even my own test app does not link, for the same reason (undefined function$UNIX2003).
Does anybody know what is the problem, and how to fix it? Or a way to work around it?
Thanks in advance,
A
PS: bonus point if somebody knows what this one means:
ld: absolute addressing (perhaps -mdynamic-no-pic) used in _Cholesky from libMyLib.a(Cholesky.o) not allowed in slidable image. Use '-read_only_relocs suppress' to enable text relocs
So the answer is: compile with ICL 10.1, not 11.1. None of the Intel libs used by 10.1 contain references to $UNIX2003 routines.
Hope it helps somebody.
A
Ultimately, you're going to need to get Intel product support from Intel, but if you want to sell Mac software that actually works then you should probably just use the same toolchain as everyone else and forget about it.

Resources