Compile Cyanogenmod 10 for Galaxy Nexus

This tutorial will outline the process to compile Cyanogenmod 10 for the GSM Galaxy Nexus (aka maguro, a variant of the tuna) on Ubuntu 12.04 LTS.  This process has changed a bit over time, notably with new hassles to configure the Oracle Java JDK.  While the tutorial is specific to the Galaxy Nexus, it generalizes to most devices supported by Cyanogenmod 10.   Begin by installing the package dependencies:

sudo apt-get install git-core gnupg flex bison gperf build-essential \
zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev \
libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 \
libgl1-mesa-dev g++-multilib mingw32 openjdk-6-jdk tofrodos \
python-markdown libxml2-utils xsltproc zlib1g-dev:i386 \
libsdl1.2-dev libesd0-dev libwxgtk2.6-dev squashfs-tools \
pngcrush schedtool lib32readline-gplv2-dev

sudo ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so

The next step is to download and configure the most recent Java JDK from Oracle.  This part of the tutorial is based on a nice tutorial from John Bokma.

Download the JDK from Oracle here:

sudo mkdir -p /usr/local/java

sudo mv ~/Downloads/jdk-6u31-linux-x64.bin /usr/local/java

cd /usr/local/java

sudo chmod +x jdk-6u31-linux-x64.bin

sudo ./jdk-6u31-linux-x64.bin

The installer will attempt to open a browser, but will fail. Presumably this is because the browser is unable to start as root, but this doesn’t seem to affect the install at all.  Now remove the installer, and create a symlink to /usr/local/java/latest.  This way a new JDK can easily be configured by just moving the /usr/local/java/latest symlink to the most recent version:

sudo rm jdk-6u31-linux-x64.bin

sudo ln -s jdk1.6.0_31 /usr/local/java/latest

Next we will need to configure some environmental variables so the JDK will be recognized. Add the JAVA_HOME and JRE_HOME . For example,

sudo gedit /etc/environment

Then replace the contents with the following:

JAVA_HOME="/usr/local/java/latest" JRE_HOME="/usr/local/java/latest/jre" PATH="/usr/local/java/latest/bin:\ /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games"

If you don’t want to log out and log back in to have the updated /etc/environment parsed by the system, you can use the ‘source’ command:

source /etc/environment

You can test if it is working correctly using

java -version  #  and

javac -version

The output should look something like this:

java version “1.6.0_31″ Java(TM) SE Runtime Environment (build 1.6.0_31-b04) Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01, mixed mode)

Next, install and configure the Android SDK, assuming you haven’t done this already (more thorough info here):

wget http://dl.google.com/android/android-sdk_r20.0.3-linux.tgz

tar -xvzf android-sdk_r20.0.3-linux.tgz

rm android-sdk_r20.0.3-linux.tgz

cd android-sdk-linux tools/android

update sdk – -no-ui

It could take quite a while for all of the updates to the Android SDK to download and install. Once that has completed,   Then, get the repo tool (a wrapper for git) and make it executable.

mkdir -p ~/bin

curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo

chmod a+x ~/bin/repo

Finally we can initialize and sync the repo. Change the -b option to checkout another branch (like -b ics). NOTE: reboot may be required for repo to work!

mkdir -p ~/cm

cd ~/cm

repo init -u git://github.com/CyanogenMod/android.git -b jb

repo sync -j16

After the source has synched, we need to run a script to get the global prebuilt binaries, including ROM Manager and Terminal.

cd ~/cm/vendor/cm

./get-prebuilts

The next step is to get the proprietary device-specific binaries extracted into the source tree.  This can be accomplished in two ways: downloading from Google, and unzipping each individually into the tree (tedious), or by pulling from a device that is running the same version of Cyanogenmod as you are attempting to build.  For the Galaxy Nexus, this process is:

cd ~/cm/device/samsung/maguro

./extract-files.sh

Now setup the environment with envsetup

cd ~/cm

. build/envsetup.sh

Execute the ‘brunch’ command to see the list of build targets, and make your selection.

brunch

Once a selection is made, the build should start. If it doesn’t, try running the ‘lunch’ instead. Make your selection, then run ‘mka bacon’

lunch

mka bacon

If that doesn’t work either, explicitly execute ‘make bacon’. You can use the -j compiler flag to enable parallel make.  The recommended use is ‘processor cores + 1′, e.g. 5 if you have a quad core processor:

make -j[#ofcpus] bacon

Once the build completes, the output will be located in ~/cm/out/target/product/maguro/.  This folder contains the system and boot images, as well as a compressed and signed update.zip. Push the file to the sdcard of the device, and reboot into recovery:

adb push ~/cm/out/target/product/maguro/cm-10-20121002-UNOFFICIAL-maguro.zip /sdcard/

adb reboot recovery

Once booted into recovery, MAKE A BACKUP, then flash the update.zip.

About Michael Mitchell

Michael received his MS in Computer Science from the Florida State University in 2011 and is currently working on a PhD. He serves as system administrator and tech lead for the FSU Mobile Lab, and is active in the FSU Operating Systems & Storage group. Michael’s research is currently funded by the National Science Foundation and includes work in mobile operating systems, context-aware computing, mobile security, and semantic file-systems. For more information about Michael and his work, check out michaeljmitchell.com and mitchtech.net