Creating a Android/AOSP Build machine on Ubuntu 20.04

Introduction

In this guide I will be going through the process of setting up an Ubuntu 20.04 LTS machine for building custom Android ROMs. This will be done by setting up our machine, getting the Android Open Source Project's (AOSP) code from Google and actually building it. This guide will be aimed at building a Android 9 image for the Pixel 2 although this process should work on any Pixel device and possibly others. Given the size of the Android project, building will take a large amount of resources and time (several hours)

Requirements

  • Fresh Ubuntu 20.04 Install
  • Root privileges (or sudo)
  • 300GB Disk space (or 180GB for source just for a single version of Android

Recommended Specs

I recommend doing this on a machine with the following specs

  • 300+ GB SSD
  • 12 CPU cores
  • 16GB RAM

At the end of the day, the faster the machine, the faster the build. The slower the machine, the slower the build!

Setting up our machine

Updating

First thing we are going to want to do is do an apt update and upgrade to make sure we have the latest versions of all of our packages. This will be helpful for later when we do a big install.

sudo apt update
sudo apt upgrade

Installing required packages

Now we have the latest versions of all the packages we require, lets install everything we need to build Android!

sudo apt install openssh-server screen python git openjdk-8-jdk android-tools-adb bc bison \
build-essential curl flex g++-multilib gcc-multilib gnupg gperf imagemagick lib32ncurses-dev \
lib32readline-dev lib32z1-dev  liblz4-tool libncurses5-dev libsdl1.2-dev libssl-dev \
libxml2 libxml2-utils lzop pngcrush rsync schedtool squashfs-tools xsltproc yasm zip zlib1g-dev \
libtinfo5 libncurses5

As you can see from the screenshot, this requires a lot of packages and may take a while to download.

Downloading Sources

Setting up repo tool

In this next section, we are going to start the process of downloading all of the Android source code from Google. All of this code is stored across hundreds of git repositories. To handle downloading all of these, Google have released a tool called repo. We will need this to continue.

sudo wget 'https://storage.googleapis.com/git-repo-downloads/repo' -P /usr/local/sbin/
sudo chmod +x /usr/local/sbin/repo

You can test to make sure repo works by typing in repo. If you get the following, it should work

error: repo is not installed.  Use "repo init" to install it here.

You will also need to setup git - These details will be used to identify you if you ever decide you want to contribute to AOSP.

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

Finding the right branches for you

You can find the right build numbers / branch names / codenames here. Its worth noting the correct tag for whatever device you want to build for. For example, I will be using the tag android-9.0.0_r34 to build for the Pixel 2 device. This has the build id of PQ2A.190305.002

Download sources for branch

This could take a while so its worth creating a screen session so we can pickup where we left off later if we get disconnected.

screen -S aosp

Change to the directory you want the sources to be downloaded to - I have a seperate drive mounted to /aosp

cd /aosp

This command will then download all of the sources that are required for the branch mentioned after the b tag.

repo init -u https://android.googlesource.com/platform/manifest -b android-9.0.0_r34

If you are worried about space, you can use the --depth=1 flag to the end of the command to only download source for your particular branch.

repo init -u https://android.googlesource.com/platform/manifest -b android-9.0.0_r34 – depth=1

When you do this, you should see something like this:

You can now sync to download all required files. The -j12 flag tells repo to use 12 cores when syncing. Change this to whatever is appropriate for your system.

repo sync -j12

This may take a while depending on the speed of your connection. Doing this on my system with a depth of 1 downloaded about 16GB and used 51GB disk space.

Proprietary Drivers

Before you are able to build, you will need to make sure that you have the device specific drivers downloaded if there are any. For Google Devices, this is pretty straight forward. You will need to go to Driver Binaries page and download the files for your device/codename. For me, this will be the links in the Pixel 2 binaries for Android 9.0.0 (PQ2A.190305.002) section. Make sure this is definitely for your device variant as there may be newer models which use different drivers. If you get the wrong ones, the device will not boot. Wget these files into the root of the AOSP directory

wget https://dl.google.com/dl/android/aosp/google_devices-walleye-pq2a.190305.002-78f45eb0.tgz
wget https://dl.google.com/dl/android/aosp/qcom-walleye-pq2a.190305.002-a7c70412.tgz

Once these are downloaded, you will need to extract them

tar -xzf qcom*
tar -xzf google_devices*

After this, you should notice there are two new files extract-google_devices-walleye.sh and extract-qcom-walleye.sh

You will need to execute each of these are then accept their terms and conditions.

./extract-google_devices-walleye.sh

and

./extract-qcom-walleye.sh

I recommend spamming the SPACE key until you are prompted with Type "I ACCEPT" if you agree to the terms of the license:. You can then type in I ACCEPT and return.

Building

Once you have all of the sources downloaded, you are almost ready to build. Before this however you will need to source the guild environment setup script. This will put all of the required build tools and functions into your PATH. You will need to do this every time you get a new terminal session. To be safe, just do it before every build.

source build/envsetup.sh

You can now use the lunch command (you will need to do this every time you want to build). This will load up a bunch of device profiles

lunch

The output for me is as follows:

You're building on Linux

Lunch menu... pick a combo:
     1. aosp_arm-eng
     2. aosp_arm64-eng
     3. aosp_mips-eng
     4. aosp_mips64-eng
     5. aosp_x86-eng
     6. aosp_x86_64-eng
     7. aosp_car_arm-userdebug
     8. aosp_car_arm64-userdebug
     9. aosp_car_x86-userdebug
     10. aosp_car_x86_64-userdebug
     11. mini_emulator_arm64-userdebug
     12. m_e_arm-userdebug
     13. m_e_mips64-eng
     14. m_e_mips-userdebug
     15. mini_emulator_x86_64-userdebug
     16. mini_emulator_x86-userdebug
     17. uml-userdebug
     18. aosp_crosshatch-userdebug
     19. aosp_blueline-userdebug
     20. aosp_cf_x86_auto-userdebug
     21. aosp_cf_x86_phone-userdebug
     22. aosp_cf_x86_tablet-userdebug
     23. aosp_cf_x86_tablet_3g-userdebug
     24. aosp_cf_x86_tv-userdebug
     25. aosp_cf_x86_wear-userdebug
     26. aosp_cf_x86_64_auto-userdebug
     27. aosp_cf_x86_64_phone-userdebug
     28. aosp_cf_x86_64_tablet-userdebug
     29. aosp_cf_x86_64_tablet_3g-userdebug
     30. aosp_cf_x86_64_tv-userdebug
     31. aosp_cf_x86_64_wear-userdebug
     32. cf_x86_auto-userdebug
     33. cf_x86_phone-userdebug
     34. cf_x86_tablet-userdebug
     35. cf_x86_tablet_3g-userdebug
     36. cf_x86_tv-userdebug
     37. cf_x86_wear-userdebug
     38. cf_x86_64_phone-userdebug
     39. cf_x86_64_tablet-userdebug
     40. cf_x86_64_tablet_3g-userdebug
     41. cf_x86_64_tv-userdebug
     42. cf_x86_64_wear-userdebug
     43. aosp_marlin-userdebug
     44. aosp_marlin_svelte-userdebug
     45. aosp_sailfish-userdebug
     46. aosp_walleye-userdebug
     47. aosp_walleye_test-userdebug
     48. aosp_taimen-userdebug
     49. hikey-userdebug
     50. hikey64_only-userdebug
     51. hikey960-userdebug

Which would you like? [aosp_arm-eng]

From this list, select the most appropriate profile for your device. E.g. aosp_walleye-userdebug for the pixel 2.

When building in the future, you can just type in

lunch aosp_walleye-userdebug

The output of this should be something like this:

============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=9
TARGET_PRODUCT=aosp_walleye
TARGET_BUILD_VARIANT=userdebug
TARGET_BUILD_TYPE=release
TARGET_ARCH=arm64
TARGET_ARCH_VARIANT=armv8-a
TARGET_CPU_VARIANT=cortex-a73
TARGET_2ND_ARCH=arm
TARGET_2ND_ARCH_VARIANT=armv8-a
TARGET_2ND_CPU_VARIANT=cortex-a73
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-5.3.0-42-generic-x86_64-Ubuntu-19.10
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=PQ2A.190305.002
OUT_DIR=out
============================================

Now you are ready to build. This can be done using the make command. The number of 12 can be replaced with the number of cores you would like to allocate to the build process. Beware that building android takes a large amount of RAM and CPU and may take several hours. It is also very IO intensive so if you are using a slower hard drive, it may also take a long time.

make -j12 

Flashing

After successfully building you should be able to flash your Android ROM on to your device.

A specific guide for windows can be found here: Flashing your custom ROM from your AOSP build machine on Windows

Assuming that the Pixel 2 is unlocked and booted into the bootloader and plugged into the machine you are building on, you should be good to go. First of all, set the following environment variable with this command:

export ANDROID_PRODUCT_OUT=/aosp/out/target/product/walleye

After this, you should be able to just type

fastboot flashall -w

The -w flag tells fastboot to wipe the data partition. If you don't do this after the initial install, it may not boot.