Compiling Android on Ubuntu 16.04

New day, same old Ubuntu

Another Ubuntu release, another set of instructions to get teh Android/AOSP source code to compile.

NOTE: This only applies to the Ubuntu 16.04 x64 (64-bit) image, and will not compile on the i386/x86 (32-bit) image, as AOSP dropped 32-bit build host support.

Ubuntu has opted to dump OpenJDK7 in the Xenial Repositories. This just means we will need to add a custom PPA to install JDK7.

Now, why go with OpenJDK7 and not OpenJDK8?

Well, OpenJDK7 is required to build most popular AOSP 6.0 ROM Sources as of right now, some examples include: DU, PN, AOSP 6.0 tags, OmniROM, and Android-x86.

Also worth nothing that in order to build Android >=4.4.x you will need Oracle Java 6.

The only use case for OpenJDK8 at the moment would be those who only build CyanogenMod or any derivative for that matter, as they’ve back-ported JDK8 compatibility, or the ‘master’ branch of AOSP.

How do I setup my environment?

Follow these instructions exactly (don’t just throw ‘sudo’ around either, it is only to be used in specific cases): 1) Remove all traces of Java: sudo apt-get remove openjdk-* icedtea-* icedtea6-*

2) Add Xenial OpenJDK7 PPA & Fetch the new packages index: sudo add-apt-repository ppa:openjdk-r/ppa && sudo apt-get update

3) Install all currently available updates to ensure no packages are broken: sudo apt-get upgrade && sudo apt-get dist-upgrade

4) Install OpenJDK7 and all Android Build dependencies: sudo apt-get install adb fastboot openjdk-7-jdk git ccache automake lzop bison gperf build-essential zip curl zlib1g-dev zlib1g-dev:i386 g++-multilib python-networkx libxml2-utils bzip2 libbz2-dev libbz2-1.0 libghc-bzlib-dev squashfs-tools pngcrush schedtool dpkg-dev liblz4-tool make optipng maven python-mako python3-mako python python3 syslinux-utils google-android-build-tools-installer

  • To install OpenJDK8, replace openjdk-7-jdk with openjdk-8-jdk
  • To install Oracle Java 6, replace openjdk-7-jdk with oracle-java6-installer NOTE: You can install all three Java versions, you will just need to select the default using the update-alternatives mentioned command later in this post.

5) Remove all unnecessary packages: sudo apt-get autoremove

6) Make a user accessible folder, and add it to path: mkdir ~/bin && echo "export PATH=~/bin:$PATH" >> ~/.bashrc

NOTE: This folder can be anywhere your user can write to.

7) Enable CCACHE to speed up builds: echo "export USE_CCACHE=1" >> ~/.bashrc

8) Reset your bash environment source ~/.bashrc

How do I sync the source?

1) Configure git git config --global user.name "John Doe" git config --global user.email johndoe@example.com NOTE: (Replace with your Name & Email Address)

2) Download repo, make it executable, and put it in our local $PATH folder: curl http://commondatastorage.googleapis.com/git-repo-downloads/repo > ~/bin/repo && chmod a+x ~/bin/repo

3) Make a folder for your ROM source of choice (in this case ‘android’), and initialize the repo: mkdir ~/android && cd ~/android repo init -u https://github.com/ROM/UrlOfManifestofROM.git -b BranchName

NOTE: Replace the URL and branch name with the ROM and branch/tag you wish to sync, so for CyanogenMod (now LineageOS) that would look like repo init -u https://github.com/LineageOS/android.git -b cm-13.0. For AOSP it would look like repo init -u https://android.googlesource.com/platform/manifest -b android-6.0.1_r81.

4) Sync the source tree: repo sync -j4 --force-sync

NOTE: This will sync roughly 75 GB of data, go get a coffee and come back, or depending on your ISP, come back to this tomorrow ;p

How do I build?

1) Setup your build environment: . build/envsetup.sh

2) Choose here:

  • If you want to fetch device dependencies, and your ROM officially supports the target device, or you’re building AOSP for a Google device - goto step 3) a)
  • If you want to build using local device tree, repo, and kernel directories – goto step 3) b) 3) a) breakfast RomTag_DeviceCodeName-BuildType - e.g. breakfast cm_mako-userdebug to build LineageOS for the Nexus 3) b) lunch RomTag_DeviceCodeName-BuildType - e.g. breakfast nexus_molly-userdebug to build PureNexus for the ADT-1 using local trees

Note: If you don’t know your device codename, Google it.

4) Either extract proprietary binaries like the extract-files.sh/proprietary-files.txt script in the device/$oem/$codename repo says to, or if that isn’t present, look for the binaries hosted somewhere reputable (for CyanogenMod/LineageOS check out TheMuppets.

5) Build the ROM: mka -j8 bacon

  • mka is just make with schedtool to calculate core count
  • -j8 is number of threads (for Intel multiply core count by 2, for others just use the core count)
  • bacon is most custom ROM’s target for a flash-able .zip archive format, if you get an error like No Target to Make: bacon, try otapackage instead.

6) Collect the ROM:

ls -al ~/android/out/target/product/ROMNAME-DATE.zip

7) Flash ROM & Enjoy!

Additional Notes

  • Some ROMs don’t sync in vendor repos by default. You’ll need to do this by fetching your OEM’s vendor from https://github.com/TheMuppets and cloning it to vendor/$oem.
  • Getting random Java or Host Binary (build output shows it building in the ‘out/host’ directory) related errors? Try a lower -j#, or, just exclude that>
  • To change your default Java version, use these two commands Make sure to run them both, as mixing and matching Java versions will not go well!: sudo update-alternatives --config java sudo update-alternatives --config javac
  • Getting Random HOST ART Library Errors? A common error going around right now is the generic ‘libart.so’ failure to build due to a linker error. This is due to a recent update in the BinUtils, to fix it run the following commands to pick the

cd ~/PathToROMSource/art

git remote add los https://github.com/LineageOS/android_art.git

git fetch los

git cherry-pick e5c6b049f3c716be60bc82d79c44c451f49b4ad5

git cherry-pick 0299788b7a974841aa3324a573fbf04f49a4f23c

Thats it! Have fun building your ROM of choice from source!

Written on April 22, 2016