Building Android O with a Mac
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
- Install Xcode: https://developer.apple.com/xcode/
- Install Xcode command line tools with:
xcode-select --install
- Install Homebrew with:
/usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
- Install JDK with: https://docs.oracle.com/javase/8/docs/technotes/guides/install/mac_jdk.html
- Check your Java version:
$ 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:
- Download Android Image: https://developers.google.com/android/images
- Unzip the archive
- Execute the following command lines:
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))