[Android Software Development] ArmanUV:
There are a lot of toturials for building CM9 on ubuntu or CM7 on Mac but I couldn't find a decent toturial for building CM9 on Mac (specially Lion). Development in AOSP/CM land is rapid and guides frequently need updating. I had to spend a little time to figure everything out and I decided to share it here.

This tutorial is for building CM9 (ICS) for Galaxy Nexus GSM (maguro) on Mac OS X Lion 10.7.3 using Xcode 4.3 and homebrew . You can easily make the instructions work for most other cm9 devices, but I wouldn't know anything about that.

DISCLAIMER: I'm not responsible if you blow yourself up, blah blah blah

However, I've tried to make this as noob friendly as possible because, well I'm a noob myself :D

Instrunctions:

UPADTE (MAY 29TH) : The Xcode 4.3 default compiler (llvm-gcc) used to be incompatible with CM9. Thanks to jocelyn and topprospect, the LLVM compatibility patches from mainline AOSP are now merged into CM9. Therefore, you can now use Xcode 4.3 and its command line tools without installing another compiler. However, since GCC is still the only officially supported compiler, incompatibilites with llvm-gcc could still be introduced with future updates. Therefore, if your build fails, it might be worth it to try installing and compiling with GCC 4.2. See the Troubleshooting section for more info.

Now that we have Xcode 4.3 and Xcode command line tools (CLT) installed, let's continue.

Open Terminal and run

java

if you don't have Java, you will get a prompt asking you to download and install Java. Go ahead and install it.

If you don't have adb and fastboot working, download the android-sdk from google (version r18 as of now) and put it in /usr/local/ and rename the folder to "android-sdk".

Install the homebrew package manager

/usr/bin/ruby -e "$(/usr/bin/curl -fsSL https://raw.github.com/mxcl/homebrew/master/Library/Contributions/install_homebrew.rb)"

To make sure that homebrew and android-sdk executables are in $PATH:

touch ~/.bash_profile && echo "PATH=/usr/local/bin:/usr/local/sbin:$PATH:/usr/local/android-sdk/tools:/usr/local/android-sdk/platform-tools" >> ~/.bash_profile

Relaunch Terminal for the change to take effect.

At this point you can run

brew doctor

to detect any problems there might be (Homebrew may instruct you to use the xcode-select utility to select the xcode installation path). Hopefully, your system is raring to brew :D

Now we have to install a bunch of packages:

brew install git coreutils findutils gnu-sed gnupg pngcrush repo

We now need to create a couple of symlinks so that the gnu versions of 'sed' and 'find' are used rather than the osx provided versions :

ln -s /usr/local/bin/gfind /usr/local/bin/find && ln -s /usr/local/bin/gsed /usr/local/bin/sed && ln -s /usr/local/bin/gstat /usr/local/bin/stat

It's time to create a case sensitive image which will hold our working directory:

hdiutil create -type SPARSE -fs "Case-sensitive Journaled HFS+" -size 40g -volname "android" -attach ~/Desktop/Android

Now we have a disk image in ~/Desktop/Android. Mount it if it's not mounted already. (Don't be picky about the size, the image will only take as much as space as its contents).

Now we need to create a working directory inside the mounted volume:

cd /Volumes/android && mkdir cm9 && cd cm9

We can initialize and download the source now:

repo init -u git://github.com/CyanogenMod/android.git -b ics && repo sync && say 'finished'

Now we need to get the required proprietry files for our device. We can get these from the device itself. Connect your phone (make sure USB Debugging is enabled) and run the following (for maguro):

cd /Volumes/android/cm9/device/samsung/maguro/ && ./extract-files.sh

[If you see errors in the output from extract-files.sh, see the Troubleshooting section below]

For Google devices,we can also get them directly from google. For maguro, download the 3 files and extract them to /Volumes/android/cm9. Then,

cd /Volumes/android/cm9
/Volumes/android/cm9/extract-broadcom-maguro.sh
/Volumes/android/cm9/extract-imgtec-maguro.sh
/Volumes/android/cm9/extract-samsung-maguro.sh

We also need the prebuilts (like ROM manager and Term.apk):

/Volumes/android/cm9/vendor/cm/get-prebuilts

You can optionally tell the build to use the ccache tool. CCache acts as a compiler cache that can be used to speed-up rebuilds :

export USE_CCACHE=1 && /Volumes/android/cm9/prebuilt/darwin-x86/ccache/ccache -M 20G

Default is 1GB. Anything between 20GB-50GB should be fine.

Before starting the build, we need to workaround an issue with Lion and compiling the QEMU emulator.

[This step doesn't seem to be needed anymore. QEMU is automatically ignored on OS X/Darwin]

If you build now, you're probably gonna get kernel build errors regarding the missing elf.h header (this error might be device specific). Fortunately, we already have this file downloaded, so we only need to copy it to /usr/local/include:

cp /Volumes/android/cm9/external/elfutils/libelf/elf.h /usr/local/include

FINALLY, we are ready to build:

cd /Volumes/android/cm9 && source build/envsetup.sh && brunch

Pick your device from the list and enter the number. For maguro, you could use "brunch maguro" instead and skip the menu. Depending on your system, this will take 30min-4hours.

You should now see a beautiful zip file waiting to be flashed:

​Troubleshooting:

The extract script for maguro seems to be a little outdated, as it doesn't pull the gps proprietary blob. You can either use the google provided scripts, or add koush's git repository for your device to your local_manifest.xml.

As explained above, the CM9 source is currently compatible with llvm-gcc. In the future, if llvm-gcc fails to build correctly, you should try installing and compiling using GCC4.2 (the Xcode 3 compiler). You can install apple-gcc4.2 from homebrew:

brew install https://raw.github.com/Homebrew/homebrew-dupes/master/apple-gcc42.rb

This version of gcc can happily coexist with Xcode 4.x .

So now you have GCC 4.2 installed, but it won't be used unless we update the corresposing environment variables:

export CC=/usr/local/bin/gcc-4.2 && export CXX=/usr/local/bin/g++-4.2

Notice that using the export command is temporary. If you relaunch Terminal, you will need to set these again. However, this is a good thing, because changing these values permanently (by putting them in ~/.bash_profile) can interfere with other builds.

If you use this method, the build might fail while compiling "external/zlib/x86/adler32.c". It appears that a recent change in zlib has introduced an incompatibility with gcc 4.2. you have to revert the following 2 commits:

cd external/zlib
git revert dd6786cae3f4493faa6661d5f74db587932f15d7
git revert 13bf40af68236c961542bdee1d4b7c0176bf15a0

Alternatively, you can add topprospect's zlib on github (which has those commits reverted) to your local_manifast.xml. Simply run:

nano /Volumes/android/cm9/.repo/local_manifest.xml

and add the following line

<project name="dferg/android_external_zlib" path="external/zlib" remote="github" />

If you get a build error, and your error is not covered here, copy the last 20-30 lines of the build output AND the output from the following command into pastebin and post the link. Hopefully me or someone else will help you.

echo -e "\nENV:\n$(env)\n\nWHICH GCC\n:$(which gcc)\n\nWHICH G++:\n$(which g++)\n\nWHICH CC:\n$(which cc)\n\nWHICH C++:\n$(which c++)\n\nBREW DOCTOR:\n$(brew doctor)\n\nBREW LIST:\n$(brew list)\n\n/USR/BIN:\n$(ls -l /usr/bin | grep gcc)\n\n/USR/LOCAL/BIN:\n$(ls -l /usr/local/bin | grep gcc)\n\n"

​Notes/Extras:

To quickly setup your environment, add an alias like the following to ~/.bash_profile:

alias cm9env="hdiutil attach PATH-TO-DISK-IMAGE -mountpoint /Volumes/android && cd /Volumes/android/cm9 && source ./build/envsetup.sh && export USE_CCACHE=1"
alias cm9build="cm9env && make clobber && reposync && brunch maguro"

Now you can save time by using "cm9env" to get your environment setup or "cm9build" to compile a clean updated build.

To clear your output directory for a new build, run "make clobber". You probably don't need this if you've only changed a few lines of code.

To cherry pick yet-to-be-merged changes from the gerrit instance:

Enjoy your custom built CM9!