Building the Open Source Tool Chain on Leopard, in /Developer by NerveGas
With the release of the Apple SDK, I've been asked by a few if it were possible to build the open source tool chain in /Developer, in keeping with Apple's screwey form factor for cross-compilers. I don't think it's particularly necessary, but I thought I'd give it a whack, just for giggles. There are a few ugly hacks involved to do the initial build/install, but once it's going, things seem to work just fine. Please let me know if you come across workarounds for these.
The Apple SDK uses the platform 'iPhoneOS'. It should be technically possible to share this set of directories, but just to keep things logically partitioned, we'll use the “iPhoneFOSS” platform below. Feel free to change this back to iPhoneOS if you'd like to stick with the standard.
$ PLATFORM=iPhoneFOSS $ DEV=/Developer/Platforms/${PLATFORM}.platform/Developer $ SDK=$DEV/SDKs/${PLATFORM}.sdk $ sudo mkdir -p $SDK/Versions/iPhoneFOSS1.1.sdk $ sudo ln -s $SDK/Versions/iPhoneFOSS1.1.sdk $SDK/Versions/Current $ SDK=$SDK/Versions/Current $ PATH=$PATH:$DEV/bin
Check out a copy of LLVM, Low-Level Virtual Machine compiler architecture, needed by the cross-compiler. Currently, due to issue 70, we are limited to revision 42498.
$ svn co http://llvm.org/svn/llvm-project/llvm/trunk llvm-svn -r 42498 $ pushd llvm-svn
Configure LLVM using the appropriate target prefixes, then build and install.
$ ./configure --prefix=$DEV --exec-prefix=$DEV --enable-optimized $ make ENABLE_OPTIMIZED=1 $ sudo make install $ LLVMOBJDIR=`pwd` $ popd
The various tool chain components can be found in a single SVN. You'll also want to switch out the odcctools repository for Saurik's updated tools, which include support for iPhone FW 1.2/2.0.
$ svn checkout http://iphone-dev.googlecode.com/svn/trunk/ iphone-dev $ pushd iphone-dev $ pushd odcctools $ svn switch http://iphone-dev.googlecode.com/svn/branches/odcctools-9.2-ld $ popd
$ mkdir -p build/odcctools $ pushd build/odcctools $ sh ../../odcctools/configure --target=arm-apple-darwin --disable-ld64 \ --prefix=$DEV --exec-prefix=$DEV $ export INCPRIVEXT="-isysroot /Developer/SDKs/MacOSX10.4u.sdk" $ make $ sudo make install $ popd
In order to build the rest of the tool chain, you'll need to download the iPhone's frameworks and libraries. This requires a jail broken device. In the example below, you'll use ssh to grab the files from your iPhone. Replace [IP] with the IP address of your iPhone.
$ mkdir ~/iphone-filesystem $ pushd ~/iphone-filesystem $ scp -r root@iphone:/System/Library/Frameworks . $ scp -r root@iphone:/System/Library/PrivateFrameworks . $ scp -r root@iphone:/usr/lib . $ mkdir -p ./System/Library ./usr $ mv Frameworks ./System/Library $ mv PrivateFrameworks ./System/Library $ mv lib ./usr $ sudo mv ./* $SDK/../iPhoneOS1.1.sdk $ popd $ rm -r ~/iphone-filesystem
Now, you're ready to install the system headers, used to compile against the private APIs on the iPhone.
$ pushd include $ ./configure --with-macosx-sdk=/Developer/SDKs/MacOSX10.4u.sdk --prefix=$SDK $ sudo bash install-headers.sh $ popd
$ mkdir -p build/csu $ pushd build/csu $ ../../csu/configure --host=arm-apple-darwin --prefix=$SDK $ sudo make install $ popd
$ sudo mv /usr/include /usr/include.old $ sudo ln -s $SDK/include /usr/include $ sudo ln -s $SDK/lib/crt1.o $SDK/lib/crt1.10.5.o $ sudo ln -s $SDK/lib/dylib1.o $SDK/lib/dylib1.10.5.o $ mv llvm-gcc-4.0-iphone/configure llvm-gcc-4.0-iphone/configure.old $ sed 's/^FLAGS_FOR_TARGET=$/FLAGS_FOR_TARGET=${FLAGS_FOR_TARGET-}/g' \ llvm-gcc-4.0-iphone/configure.old > llvm-gcc-4.0-iphone/configure $ mkdir -p build/llvm-gcc-4.0-iphone $ pushd build/llvm-gcc-4.0-iphone $ sh ../../llvm-gcc-4.0-iphone/configure \ --prefix=$DEV \ --exec-prefix=$DEV \ --enable-llvm=`$DEV/bin/llvm-config --obj-root` \ --enable-languages=c,c++,objc,obj-c++ \ --target=arm-apple-darwin \ --enable-sjlj-exceptions \ --with-heavenly=$SDK $ make LLVM_VERSION_INFO=2.0-svn-iphone-dev-0.3-svn $ sudo make install $ sudo rm /usr/include $ sudo mv /usr/include.old /usr/include $ popd
Now that you've got the tool chain compiler running from a different path, you'll need to add that path to your PATH variable. Add the following lines to the end of your .profile:
PLATFORM=iPhoneFOSS DEV=/Developer/Platforms/${PLATFORM}.platform/Developer SDK=$DEV/SDKs/${PLATFORM}/Versions/Current PATH=$PATH:$DEV/bin
You'll also need to start using “proper” compiler flags in your makefile, to tell the compiler where to find your frameworks and libraryes. Use something like this in your makefile:
PLATFORM=iPhoneFOSS DEV=/Developer/Platforms/${PLATFORM}.platform/Developer SDK=$DEV/SDKs/${PLATFORM}.sdk/Versions/Current CC = arm-apple-darwin-gcc LD = $(CC) LDFLAGS = -lobjc \ -framework CoreFoundation \ -framework Foundation \ -framework UIKit \ -L"$(SDK)/usr/lib" \ -F"$(SDK)/System/Library/Frameworks" \ -F"$(SDK)/System/Library/PrivateFrameworks" CFLAGS = -I"$(SDK)/include"
Congratulations! You now have a working tool chain installed in /Developer!
To add support for additional platforms, just repoint the Current symlink and add the necessary flags. 2.0 requires -fobjc-abi-version=2 in both CFLAGS and LDFLAGS.