[GUIDE][ICS] Compile Cyanogenmod 9 on Mac OS X Lion

Search This thread

ArmanUV

Senior Member
Jan 26, 2012
839
220
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
    Code:
    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
    Code:
    /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:
    Code:
    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
    Code:
    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:
    Code:
    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 :
    Code:
    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:
    Code:
    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:
    Code:
    cd /Volumes/android && mkdir cm9 && cd cm9
  • We can initialize and download the source now:
    Code:
    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):
    Code:
    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,
    Code:
    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):
    Code:
    /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 :
    Code:
    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:
    Code:
    cp /Volumes/android/cm9/external/elfutils/libelf/elf.h /usr/local/include
  • FINALLY, we are ready to build:
    Code:
    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:

    Screen%20Shot%202012-05-13%20at%204.28.35%20AM.png
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:
    Code:
    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:
    Code:
    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:
    Code:
    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:
    Code:
    nano /Volumes/android/cm9/.repo/local_manifest.xml
    and add the following line
    Code:
    <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.
    Code:
    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:
    Code:
    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:
    1. Pick an open commit from CM Gerrit
    2. Under list of Patch Sets pick the latest and open cherry-pick tab
    3. Check what Git repository the url is pointing e.g. http://review.cyanog...frameworks_base
    4. In your CM9 working tree go to the corresponding directory, which in this case is something like ~/your-working-directory/frameworks/base/
    5. Now simply paste the whole line seen in CM Gerrit cherry-pick tab e.g. "git fetch http://review.cyanog....rameworks_base refs/changes/00/13100/4 && git cherry-pick FETCH_HEAD"
    It should be now included in your next compiled build. When doing repo sync again, cherry picks will be lost.[CREDIT Fihlvein from xda]

    Enjoy your custom built CM9!
 
Last edited:

grad061980

Senior Member
Dec 28, 2010
166
47
Nice write up. Thanks.

Before I start again from scratch I have a question. Does this guide apply to previous versions of mac os x (mine is 10.6.8)? I used the official android initializing build environment page & cm7 wiki page for the instructions to setup my build environment.

Also, any tips to switch from macports to homebrew?

In the past I've had to cherry pick to get my OS X build environment set up for CM9. The compile from source fails because I started with macports instead of homebrew (bad idea). I tried to switch to homebrew without success. Any tips to switch from macports to homebrew?

For the sake of keeping this page on topic a pm response is ok if that is what you prefer.
 

ArmanUV

Senior Member
Jan 26, 2012
839
220
Nice write up. Thanks.

Before I start again from scratch I have a question. Does this guide apply to previous versions of mac os x (mine is 10.6.8)? I used the official android initializing build environment page & cm7 wiki page for the instructions to setup my build environment.

Also, any tips to switch from macports to homebrew?

In the past I've had to cherry pick to get my OS X build environment set up for CM9. The compile from source fails because I started with macports instead of homebrew (bad idea). I tried to switch to homebrew without success. Any tips to switch from macports to homebrew?

For the sake of keeping this page on topic a pm response is ok if that is what you prefer.
Yes, this guide should work fine on Snow Leopard. It mostly depends on your Xcode version. If you have Xcode 3, you can skip step 1 entirely, since you already have gcc4.2 as part of Xcode.
If you have access to Xcode 4.2 and above, you will need to install gcc4.2 separately, as explained in the guide.

Now regarding Macports, I strongly suggest that you completely uninstall Macports before installing homebrew. Instructions are here: http://guide.macports.org/chunked/installing.macports.uninstalling.html

Hi thanks for this !! Helpful one question what do i change so i can do AOSP instead of cm9??
Full instructions are available on android.com : http://source.android.com/source/initializing.html
If you are using this guide, you need to change the repo initialization command to :
Code:
repo init -u https://android.googlesource.com/platform/manifest
and then do repo sync. You can setup ccache as usual. I don't think AOSP has the "brunch command", so you have to use launch and then make.
Run "lunch" and select an option from the menu. You can find more info about the options here: http://source.android.com/source/building.html. For maguro, you should use "full_maguro-userdebug".
To start the build, use
Code:
make -j$(sysctl -n hw.ncpu)
 
Last edited:
  • Like
Reactions: WonkyYew

grad061980

Senior Member
Dec 28, 2010
166
47
@ArmanUV. Sounds good & thanks for the input. I'll give the link to macports uninstall a go.
 

empyyy

Member
Feb 3, 2012
41
5
Hi, thanks for your guide, setting up the repo was no problem at all!
But: I'm getting the following error when building.
Code:
external/zlib/x86/adler32.c: In function ‘adler32_MMX’:
external/zlib/x86/adler32.c:747: error: can't find a register in class ‘GENERAL_REGS’ while reloading ‘asm’
external/zlib/x86/adler32.c:747: error: ‘asm’ operand has impossible constraints
make: *** [out/host/darwin-x86/obj/STATIC_LIBRARIES/libz_intermediates/adler32.o] Error 1
make: *** Waiting for unfinished jobs....
Seems to be a problem with the compiler, but I'm on xcode 4.3 and I've installed gcc-4.2 and set the env vars. Any help?
 

topprospect

Senior Member
Nov 28, 2011
390
2,632
Atlanta, GA
ArmanUV,

Thanks so much for posting this guide. Very helpful!

Are you having any trouble with errors like this?

Code:
external/zlib/x86/adler32.c: In function ‘adler32_MMX’:
external/zlib/x86/adler32.c:747: error: can't find a register in class ‘GENERAL_REGS’ while reloading ‘asm’
external/zlib/x86/adler32.c:747: error: ‘asm’ operand has impossible constraints

Googling for this error implies that the fix is to use a version of GCC > 4.2. But there does not seem to be a GCC 4.4 in Homebrew.

Thanks again for the guide!

EDIT: Sorry for the double post with empyyy. Seems like there is someone else having my same issue!
 
Last edited:

ArmanUV

Senior Member
Jan 26, 2012
839
220
ArmanUV,

Thanks so much for posting this guide. Very helpful!

Are you having any trouble with errors like this?

Code:
external/zlib/x86/adler32.c: In function ‘adler32_MMX’:
external/zlib/x86/adler32.c:747: error: can't find a register in class ‘GENERAL_REGS’ while reloading ‘asm’
external/zlib/x86/adler32.c:747: error: ‘asm’ operand has impossible constraints

Googling for this error implies that the fix is to use a version of GCC > 4.2. But there does not seem to be a GCC 4.4 in Homebrew.

Thanks again for the guide!

EDIT: Sorry for the double post with empyyy. Seems like there is someone else having my same issue!

Hi, thanks for your guide, setting up the repo was no problem at all!
But: I'm getting the following error when building.
Code:
external/zlib/x86/adler32.c: In function ‘adler32_MMX’:
external/zlib/x86/adler32.c:747: error: can't find a register in class ‘GENERAL_REGS’ while reloading ‘asm’
external/zlib/x86/adler32.c:747: error: ‘asm’ operand has impossible constraints
make: *** [out/host/darwin-x86/obj/STATIC_LIBRARIES/libz_intermediates/adler32.o] Error 1
make: *** Waiting for unfinished jobs....
Seems to be a problem with the compiler, but I'm on xcode 4.3 and I've installed gcc-4.2 and set the env vars. Any help?

You guys seem to have the same issue. What sort of Xcode configuration are you using? Can you post the output from "which gcc","which g++", "gcc -v", "g++ -v" and "cc -v"?
 

topprospect

Senior Member
Nov 28, 2011
390
2,632
Atlanta, GA
You guys seem to have the same issue. What sort of Xcode configuration are you using? Can you post the output from "which gcc","which g++", "gcc -v", "g++ -v" and "cc -v"?

I am on Lion 10.7.4 with Xcode 4.3.2. Here is the output that you asked for:

Code:
# echo -n "which gcc: "; which gcc; echo -n "which g++: "; which g++; echo ""; echo "gcc -v:"; gcc -v; echo ""; echo "g++ -v:"; g++ -v; echo ""; echo "cc -v:"; cc -v
which gcc: /usr/bin/gcc
which g++: /usr/bin/g++

gcc -v:
Using built-in specs.
Target: i686-apple-darwin11
Configured with: /private/var/tmp/llvmgcc42/llvmgcc42-2336.9~22/src/configure --disable-checking --enable-werror --prefix=/Applications/Xcode.app/Contents/Developer/usr/llvm-gcc-4.2 --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-prefix=llvm- --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin11 --enable-llvm=/private/var/tmp/llvmgcc42/llvmgcc42-2336.9~22/dst-llvmCore/Developer/usr/local --program-prefix=i686-apple-darwin11- --host=x86_64-apple-darwin11 --target=i686-apple-darwin11 --with-gxx-include-dir=/usr/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.9.00)

g++ -v:
Using built-in specs.
Target: i686-apple-darwin11
Configured with: /private/var/tmp/llvmgcc42/llvmgcc42-2336.9~22/src/configure --disable-checking --enable-werror --prefix=/Applications/Xcode.app/Contents/Developer/usr/llvm-gcc-4.2 --mandir=/share/man --enable-languages=c,objc,c++,obj-c++ --program-prefix=llvm- --program-transform-name=/^[cg][^.-]*$/s/$/-4.2/ --with-slibdir=/usr/lib --build=i686-apple-darwin11 --enable-llvm=/private/var/tmp/llvmgcc42/llvmgcc42-2336.9~22/dst-llvmCore/Developer/usr/local --program-prefix=i686-apple-darwin11- --host=x86_64-apple-darwin11 --target=i686-apple-darwin11 --with-gxx-include-dir=/usr/include/c++/4.2.1
Thread model: posix
gcc version 4.2.1 (Based on Apple Inc. build 5658) (LLVM build 2336.9.00)

cc -v:
Apple clang version 3.1 (tags/Apple/clang-318.0.58) (based on LLVM 3.1svn)
Target: x86_64-apple-darwin11.3.0
Thread model: posix

They are pointing to LLVM, but my CC and CXX variables point to:
Code:
env|grep 4.2
CXX=/usr/local/bin/g++-4.2
CC=/usr/local/bin/gcc-4.2

Do I need to add something to PATH? I'm sure I just missed something obvious in your instructions.. Thanks for helping!
 

ArmanUV

Senior Member
Jan 26, 2012
839
220
I am on Lion 10.7.4 with Xcode 4.3.2. Here is the output that you asked for:

Do I need to add something to PATH? I'm sure I just missed something obvious in your instructions.. Thanks for helping!

Everything checks out. I'm away from my main machine so I can't run a test build, but I suspect that a recent change is causing problems.

Now, regarding the compiler, Setting CC/CXX *should* take care of everything, but I am currently not 100% sure that somewhere in a makefile, these environment variables aren't being ignored. Since I wrote the guide, I noticed a lot of clang warnings in the build, which means that CC/CXX is not honored and /usr/bin/cc and /usr/bin/c++ is being used.

A more robust method of making sure gcc-4.2 is being used is creating symlinks to gcc-4.2 and g++-4.2 :
Code:
ln -s /usr/local/bin/gcc-4.2 /usr/local/bin/gcc
ln -s /usr/local/bin/gcc-4.2 /usr/local/bin/cc
ln -s /usr/local/bin/g++-4.2 /usr/local/bin/c++
ln -s /usr/local/bin/g++-4.2 /usr/local/bin/g++
Obviousely, a systemic method like this has its downsides but it may be the only choice without having to change CM code (especially since I lack the knowledge to do so :D )

[I recently found out that master aosp is no longer using CC/CXX to find the compiler (see ./build/core/combo/). Instead, it uses "gcc" and "g++" directly, which means that llvm-gcc will be used no matter what env variable you have. Fortunately, unlike cm9, master aosp is supposed to build fine with llvm-gcc (except for qemu, which doesn't matter for device images). ]
 
Last edited:

topprospect

Senior Member
Nov 28, 2011
390
2,632
Atlanta, GA
Everything checks out. I'm away from my main machine so I can't run a test build, but I suspect that a recent change is causing problems.

Now, regarding the compiler, Setting CC/CXX *should* take care of everything, but I am currently not 100% sure that somewhere in a makefile, these environment variables aren't being ignored. Since I wrote the guide, I noticed a lot of clang warnings in the build, which means that CC/CXX is not honored and /usr/bin/cc and /usr/bin/c++ is being used.

A more robust method of making sure gcc-4.2 is being used is creating symlinks to gcc-4.2 and g++-4.2 :
Code:
ln -s /usr/local/bin/gcc-4.2 /usr/local/bin/gcc
ln -s /usr/local/bin/gcc-4.2 /usr/local/bin/cc
ln -s /usr/local/bin/g++-4.2 /usr/local/bin/c++
ln -s /usr/local/bin/g++-4.2 /usr/local/bin/g++

Okay, just tried this. I created a new dir (/Volumes/Android/bin) that simply houses those softlinks you recommended. Then I put /Volumes/Android/bin at the beginning of my PATH. That should fix it without breaking the rest of the system, e.g. homebrew.

The GENERAL_REGS problem still exists though. Pretty sure b/c gcc 4.2.1 doesn't understand this construct properly (need a newer version of gcc).

So I backed out the change that introduced this adler32.c.

https://github.com/CyanogenMod/android_external_zlib/commit/13bf40af68236c961542bdee1d4b7c0176bf15a0

The compile is getting farther now. I have to run to work so I'll post later if it succeeds.

The weird thing is: This change was made back in December. Why would it have worked for you?
 

topprospect

Senior Member
Nov 28, 2011
390
2,632
Atlanta, GA
The compile is getting farther now. I have to run to work so I'll post later if it succeeds.

Build works (and boots!) with the following:

Code:
cd external/zlib
git revert dd6786cae3f4493faa6661d5f74db587932f15d7
git revert 13bf40af68236c961542bdee1d4b7c0176bf15a0

Note the 1st revert is just to avoid massive conflicts seen when reverting the 2nd one by itself. The 2nd revert is the one that really matters here.

So this isn't really a solution.. Seems like we need to move to a newer version of gcc or figure out a patch to adler32.c that makes it gcc 4.2 compatible.
 

empyyy

Member
Feb 3, 2012
41
5
Build works (and boots!) with the following:

Code:
cd external/zlib
git revert dd6786cae3f4493faa6661d5f74db587932f15d7
git revert 13bf40af68236c961542bdee1d4b7c0176bf15a0

The first revert works fine, however the second one gives me the following error:
Code:
$ git revert 13bf40af68236c961542bdee1d4b7c0176bf15a0
error: could not revert 13bf40a... Implement vectorized adler32 and optimized slhash
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
error: Could not parse conflict hunks in zlib.h
 

topprospect

Senior Member
Nov 28, 2011
390
2,632
Atlanta, GA
The first revert works fine, however the second one gives me the following error:
Code:
$ git revert 13bf40af68236c961542bdee1d4b7c0176bf15a0
error: could not revert 13bf40a... Implement vectorized adler32 and optimized slhash
hint: after resolving the conflicts, mark the corrected paths
hint: with 'git add <paths>' or 'git rm <paths>'
hint: and commit the result with 'git commit'
error: Could not parse conflict hunks in zlib.h

Well, run git status. You'll see that the only conflict is in the comments in zlib.h. So, you can just ignore it.
 

ArmanUV

Senior Member
Jan 26, 2012
839
220
Okay, just tried this. I created a new dir (/Volumes/Android/bin) that simply houses those softlinks you recommended. Then I put /Volumes/Android/bin at the beginning of my PATH. That should fix it without breaking the rest of the system, e.g. homebrew.

The GENERAL_REGS problem still exists though. Pretty sure b/c gcc 4.2.1 doesn't understand this construct properly (need a newer version of gcc).

So I backed out the change that introduced this adler32.c.

https://github.com/CyanogenMod/android_external_zlib/commit/13bf40af68236c961542bdee1d4b7c0176bf15a0

The compile is getting farther now. I have to run to work so I'll post later if it succeeds.

The weird thing is: This change was made back in December. Why would it have worked for you?

Build works (and boots!) with the following:

Code:
cd external/zlib
git revert dd6786cae3f4493faa6661d5f74db587932f15d7
git revert 13bf40af68236c961542bdee1d4b7c0176bf15a0

Note the 1st revert is just to avoid massive conflicts seen when reverting the 2nd one by itself. The 2nd revert is the one that really matters here.

So this isn't really a solution.. Seems like we need to move to a newer version of gcc or figure out a patch to adler32.c that makes it gcc 4.2 compatible.

Nice find. I tried to compile this morning and I ran into the same issue. This is what I don't understand: I did a couple of builds about a week ago without running into this issue. But, the latest commits on zlib are from 2 months ago.
Amazingly, the Xcode 4.3 toolchain (clang and llvm-gcc) builds this external/zlib/adler32.c just fine.

An alternative to this problem is to install an up to date gcc 4.7 :
Code:
brew install https://raw.github.com/Homebrew/homebrew-dupes/master/gcc.rb
and then create symlinks to gcc-4.7/g++-4.7. I have not tested this yet.
 
Last edited:

Top Liked Posts

  • There are no posts matching your filters.
  • 17
    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
      Code:
      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
      Code:
      /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:
      Code:
      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
      Code:
      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:
      Code:
      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 :
      Code:
      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:
      Code:
      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:
      Code:
      cd /Volumes/android && mkdir cm9 && cd cm9
    • We can initialize and download the source now:
      Code:
      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):
      Code:
      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,
      Code:
      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):
      Code:
      /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 :
      Code:
      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:
      Code:
      cp /Volumes/android/cm9/external/elfutils/libelf/elf.h /usr/local/include
    • FINALLY, we are ready to build:
      Code:
      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:

      Screen%20Shot%202012-05-13%20at%204.28.35%20AM.png
    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:
      Code:
      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:
      Code:
      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:
      Code:
      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:
      Code:
      nano /Volumes/android/cm9/.repo/local_manifest.xml
      and add the following line
      Code:
      <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.
      Code:
      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:
      Code:
      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:
      1. Pick an open commit from CM Gerrit
      2. Under list of Patch Sets pick the latest and open cherry-pick tab
      3. Check what Git repository the url is pointing e.g. http://review.cyanog...frameworks_base
      4. In your CM9 working tree go to the corresponding directory, which in this case is something like ~/your-working-directory/frameworks/base/
      5. Now simply paste the whole line seen in CM Gerrit cherry-pick tab e.g. "git fetch http://review.cyanog....rameworks_base refs/changes/00/13100/4 && git cherry-pick FETCH_HEAD"
      It should be now included in your next compiled build. When doing repo sync again, cherry picks will be lost.[CREDIT Fihlvein from xda]

      Enjoy your custom built CM9!
    3
    I forked android_external_zlib and reverted the 2 changes. Until we figure out a better solution, you can point your local_manifest.xml to my repo for external/zlib:

    git://github.com/dferg/android_external_zlib.git
    2
    Nice work man. Very helpful.
    1
    Nice write up. Thanks.

    Before I start again from scratch I have a question. Does this guide apply to previous versions of mac os x (mine is 10.6.8)? I used the official android initializing build environment page & cm7 wiki page for the instructions to setup my build environment.

    Also, any tips to switch from macports to homebrew?

    In the past I've had to cherry pick to get my OS X build environment set up for CM9. The compile from source fails because I started with macports instead of homebrew (bad idea). I tried to switch to homebrew without success. Any tips to switch from macports to homebrew?

    For the sake of keeping this page on topic a pm response is ok if that is what you prefer.
    Yes, this guide should work fine on Snow Leopard. It mostly depends on your Xcode version. If you have Xcode 3, you can skip step 1 entirely, since you already have gcc4.2 as part of Xcode.
    If you have access to Xcode 4.2 and above, you will need to install gcc4.2 separately, as explained in the guide.

    Now regarding Macports, I strongly suggest that you completely uninstall Macports before installing homebrew. Instructions are here: http://guide.macports.org/chunked/installing.macports.uninstalling.html

    Hi thanks for this !! Helpful one question what do i change so i can do AOSP instead of cm9??
    Full instructions are available on android.com : http://source.android.com/source/initializing.html
    If you are using this guide, you need to change the repo initialization command to :
    Code:
    repo init -u https://android.googlesource.com/platform/manifest
    and then do repo sync. You can setup ccache as usual. I don't think AOSP has the "brunch command", so you have to use launch and then make.
    Run "lunch" and select an option from the menu. You can find more info about the options here: http://source.android.com/source/building.html. For maguro, you should use "full_maguro-userdebug".
    To start the build, use
    Code:
    make -j$(sysctl -n hw.ncpu)
    1
    That's one interesting error. I've never tried gcc 4.7 myself. I don't think everything is compatible with it yet.
    Okay, seems to be a problem with the kernel source, since I'm building for the HTC One X. Building for the Galaxy Nexus works fine. Thanks again for your guide!