Building Android O with a Mac

Christopher Ney
Mar 26, 2018 · 6 min read

After spending several hours to analyse dozens of posts and articles to compile Android O MR1 AOSP, I decided to write a short manual to help you to build your AOSP effortlessly ;-)

This article is based on Official Android documentation: https://source.android.com/setup/requirements

My Environment

  • OS: macOS Sierra 10.12.5
  • CPU: 2,9 GHz Intel Core i5 (influence the speed compilation)
  • RAM: 8 GB 1867 MHz DDR3 (8GB minimum, recommended 16GB)
  • Disk: 200GB free space (after AOSP sources downloaded — minimum 200GB)
  • Device: Nexus 5X (bullhead)

Setup your Build Environment

xcode-select --install
  • Install Homebrew with:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
$ java -version
> java version "1.8.0_144"
  • Install GIT with:
brew install git
  • Install Python with:
brew install python
  • Install Make with:
brew install make

Creating a case-sensitive disk image

Case sensitive volume of 200GB with the following command line:

hdiutil create -type SPARSE -fs 'Case-sensitive Journaled HFS+' -size 200g ~/android.dmg

Install tools and libraries via MacPort

Install MacPorts: https://www.macports.org/install.php then type the following command line:

POSIXLY_CORRECT=1 sudo port install gmake libsdl git gnupg

Then create and edit the .bash_profile file with the following code:

cd ~
nano .bash_profile
# set the number of open files to be 1024
ulimit -S -n 1024
# Compiler cache
export USE_CCACHE=1
# mount the android file image
function mountAndroid { hdiutil attach ~/android.dmg.sparseimage -mountpoint /Volumes/android; }
# unmount the android file image
function umountAndroid() { hdiutil detach /Volumes/android; }
export PATH="/opt/local/bin:/opt/local/sbin:$PATH"
export PATH=~/bin:$PATH
export ANDROID_JAVA_HOME=$(/usr/libexec/java_home -v 1.8)
export PATH=$ANDROID_JAVA_HOME/bin:$PATH

Download AOSP source code

To identify the right branch to download, check the Build number of the target device. In our case OPM5.171019.017 which isncorresponding to the branch android-8.1.0_r18.

Branches and Builds codename: https://source.android.com/source/build-numbers#source-code-tags-and-builds

Warning: when you choose a branch be sure that the branch support the targeted device!

Select the targeted AOSP version with the branch with -b parameter: android-8.1.0_r18

source ~/.bash_profile
mkdir ~/bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/bin/repo
chmod a+x ~/bin/repo

mountAndroid
cd /Volumes/android
mkdir WORKING_DIRECTORY
cd WORKING_DIRECTORY

git config --global user.name "Your Name"
git config --global user.email "you@example.com"

repo init -u https://android.googlesource.com/platform/manifest
repo init -u https://android.googlesource.com/platform/manifest -b android-7.1.1_r1
repo sync

Building ASOP source code

Open terminal:

cd /Volumes/android/WORKING_DIRECTORY/ # Set ccache
prebuilts/misc/darwin-x86/ccache/ccache -M 50G
# Clean out directory
make clobber
# Jack server configuration
export JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx6g"
./prebuilts/sdk/tools/jack-admin kill-server
./prebuilts/sdk/tools/jack-admin start-server
# Setup environment
source build/envsetup.sh

Select the device target with lunch command, then build the sources with make command:

# Select device target
lunch
# Build sources (cofee time)
make -j4

When the build process if finished you get the following message:

[100% 7091/7091] Install system fs image: out/target/product/generic/system.imgout/target/product/generic/system.img+ maxsize=1918388736 blocksize=2112 total=1879048192 reserve=19379712#### make completed successfully (02:52:17 (hh:mm:ss)) ####

Install new Android Build on Device

Connect the Device in USB, enable the Developer Mode, then input the following command lines in you Terminal:

cd out/target/product/<product_name> 
adb reboot bootloader
fastboot oem unlock 
fastboot flashall -w

Restore Android Image

To restore an official Android Image please download the target Image and follow the instructions:

cd ~/Downloads/bullhead-opm5.171019.017/adb reboot bootloaderfastboot oem unlock
./flash-all.sh

Rebuild a single package

To rebuild a single package (example: Dialer App) instead of rebuild the entire baseline, use the following command lines:

cd WORKING_DIRECTORY
source build/envsetup.sh
# Select device target
lunch
# Rebuil single pacage (exemple Dialer)
mmm packages/apps/dialer/

The output APK path will be prompt by the console, or located at the following path:

# Recompiled package output
cd /out/target/product/<device_targeted>/obj/APPS/<app_name>_intermediates

How to install it

adb install -r out/target/product/<device_targeted>/system/priv-app/<app_name>/<app_name>.apkadb reboot

System UI

Build System UI only:

cd WORKING_DIRECTORY
source build/envsetup.sh
# Select device target
lunch
# Rebuil single pacage (exemple Dialer)
mmm frameworks/base/packages/SystemUI/

How to install it

adb install -r out/target/product/<device_targeted>/system/priv-app/SystemUI/SystemUI.apkadb reboot

Android Framework

  • Build Framework JAR only: mmm framework/base/
  • Build Framework Resources only: mmm framework/base/core/res/

How to install it

# Root the device
adb root
adb disable-verity
adb reboot
adb remount
# Remove older framework
adb shell
cd /system/framework/
rm framework-res.apk
exit
# Push the new Framework
adb push out/target/product/<device_targeted>/system/framework/framework-res.apk /system/framework/
# Reboot the device
adb reboot

Signing Build

The standard Android build uses four keys, all of which reside in build/target/product/security:

  • testkey: Generic default key for packages that do not otherwise specify a key.
  • platform: Test key for packages that are part of the core platform.
  • shared: Test key for things that are shared in the home/contacts process.
  • media: Test key for packages that are part of the media/download system.
cd /build/target/product/security/

Source: https://source.android.com/devices/tech/ota/sign_builds#certificates-keys

To sign an app with one of the existing key, use the following instruction (LOCAL_CERTIFICATE) into the associated makefile Android.mk:

Android.mk

LOCAL_CERTIFICATE := platform

Troubleshooting

Can not find Mac SDK or Required minimum for the macosx platform

Download and uncompress the exact missing Mac SDK version into the following directory:

  • /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/

Download Mac SDKs: https://github.com/phracker/MacOSX-SDKs/releases

Error: could not find jdk tools.jar

Need to defined $ANDROID_JAVA_HOME used in ~/build/core/find-jdk-tools-jar.sh

export ANDROID_JAVA_HOME=$(/usr/libexec/java_home -v 1.8)echo $ANDROID_JAVA_HOME
/Library/Java/JavaVirtualMachines/jdk1.8.0_144.jdk/Contents/Home

Download and install JDK before : http://www.oracle.com/technetwork/java/javase/downloads/java-archive-javase8-2177648.html#jdk-8u45-oth-JPR

Make error — already defined

If you got the following error during the AOSP compilation:

including ./go/src/github.com/google/gapid/third_party/khronos/SPIRV-Cross/jni/Android.mk ...build/core/base_rules.mk:183: *** go/src/github.com/google/gapid/third_party/khronos/SPIRV-Cross/jni: MODULE.TARGET.STATIC_LIBRARIES.spirv-cross already defined by go/src/github.com/google/gapid/third_party/SPIRV-Cross/jni.make: *** [out/build-aosp_arm.ninja] Error 1

Go to the already defined directory and rename simply the Android.mk file to Android_old.mk

GC overhead limit exceeded

GC overhead limit exceeded. Try increasing heap size with java option '-Xmx<size>'.FAILED: /bin/bash out/target/common/obj/JAVA_LIBRARIES/framework_intermediates/with-local/classes.dex.rspOut of memory error (version 1.2-rc4 'Carnac' (298900 f95d7bdecfceb327f9d201a1348397ed8a843843 by android-jack-team@google.com)).GC overhead limit exceeded.Try increasing heap size with java option '-Xmx<size>'.Warning: This may have produced partial or corrupted output.

To increase the the heap size use the following command lines:

export JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx6g"./prebuilts/sdk/tools/jack-admin kill-server./prebuilts/sdk/tools/jack-admin start-server

Case-insensitive filesystem

You are building on a case-insensitive filesystem.

************************************************************
You are building on a case-insensitive filesystem.
Please move your source tree to a case-sensitive filesystem.
************************************************************
Case-insensitive filesystems not supported.

Creating a case-sensitive disk image: https://source.android.com/source/initializing#setting-up-a-mac-os-x-build-environment

Fatal error file not found

If the following error is raised during the Android building process:

external/iptables/extensions/../include/linux/netfilter_ipv4/ipt_ECN.h:13:10: fatal error: 'linux/netfilter/xt_DSCP.h' file not found#include <linux/netfilter/xt_DSCP.h>

Please check the filename user or lower case. Remember that the Android building process is case-sensitive.

In this case create a symbolic name xt_dscp.h for the original file xt_DSCP.h with the following command lines:

cd external/iptables/extensions/../include/linux/netfilterln -s xt_dscp.h xt_DSCP.h

Result:

No space left on device

If the case-sensitive partition become full (no free space available):

[ 25% 2/8] build out/target/product/generic/obj/JAVA_...RARIES/SystemUI-proto-tags_intermediates/classes.jackninja: error: mkdir(out/target/product/generic/obj/JAVA_LIBRARIES/SystemUI-proto-tags_intermediates): No space left on device

Open Terminal and increase the partition size:

umountAndroid
hdiutil resize -size <new-size-you-want>g ~/android.dmg.sparseimage
mountAndroid

Missing and no known rule to make it

If the flowing error is raised during a single package compilation thought mm or mmm command:

ninja: error: 'out/target/common/obj/JAVA_LIBRARIES/metrics-helper-lib_intermediates/link_type', needed by 'out/target/common/obj/APPS/SystemUITests_intermediates/link_type', missing and no known rule to make it12:39:35 ninja failed with: exit status 1make: *** [run_soong_ui] Error 1

Compile the bidding library metrics-helper:

mma platform_testing/libraries/metrics-helper/

OR, go to the main makefile Android.mk and disable the Unit tests project compilation by commenting the include line:

Android.mk

include $(BUILD_PACKAGE)
# disable the sub-project makefile: ./tests/Android.mk
# include $(call all-makefiles-under,$(LOCAL_PATH))

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store