CN

Setting Up the Android System Development Environment

Word count: 2.1kReading time: 12 min
2018/11/01
loading

Whether you are an Android App developer or a System developer, having a foundational understanding of the Android system is extremely beneficial. I recently set up a development environment at home and decided to share the process for anyone interested.

The general steps involved are as follows:

  1. Installing Ubuntu
  2. Configuring Ubuntu
  3. Installing Essential Software
  4. Configuring Network Access (Optional)
  5. Downloading AOSP Code
  6. Setting Up the Build Environment and Compiling Pixel Code
  7. Flashing the Device
  8. Modifying and Compiling Framework, Services, and Res

Version note — reviewed October 13, 2026: The original is a 2018 environment record. Its screenshots show Ubuntu 18.04.1, PLATFORM_VERSION_CODENAME=Q, and aosp_sailfish-userdebug, but no complete manifest pins the original master checkout. The Pixel workflow remains historical. The new example uses Android 16 tag android-16.0.0_r1, Ubuntu 22.04 x86_64, and Cuttlefish x86_64. It is not presented as the latest release or as a way to flash Android 16 onto the original Pixel.

The old “512 GB SSD and a Pixel” advice needs context. For a modern workstation, the current AOSP requirements list 64-bit x86 Linux, at least 400 GB of free disk space, and 64 GB RAM. A nominal 512 GB disk does not necessarily have that much free space; multiple checkouts and outputs require more. These are planning guidelines for modern builds, not universal limits for every old branch. Reading source needs less, and running this Cuttlefish example additionally requires usable KVM. A physical phone is optional.

1. Installing Ubuntu

Ubuntu 18.04’s standard security maintenance ended in May 2023; extended maintenance has separate conditions. See the Ubuntu release lifecycle. This update uses Ubuntu 22.04 LTS instead of the old 18.04.1 mirror ISO.

  1. Obtain an amd64 image from the official Ubuntu 22.04 release directory and verify it against the published checksums.
  2. Create a bootable USB drive and back up existing data before repartitioning.
  3. Install on a suitable Linux host. A VM can work with enough disk and memory, but running Cuttlefish also requires KVM/nested virtualization to be available inside it. Being able to compile in a VM does not prove it can run the virtual device.

This was my desktop at the time. Do not treat these Linux instructions as a native macOS or Apple Silicon build procedure.

Original Ubuntu desktop from 2018

2. Configuring Ubuntu

Choose an input method and editor to suit your workflow. Vim can be installed with sudo apt install vim. Obtain adb and fastboot through Android Studio’s SDK Manager or SDK Platform-Tools. AOSP builds also produce host tools; confirm which copy your shell uses before mixing installations:

1
2
3
4
command -v adb
adb --version
command -v fastboot
fastboot --version

Physical-device access on Linux also requires USB debugging authorization and suitable device permissions. Establish connectivity before deployment.

3. Installing Essential Software

I listed VS Code, Android Studio, and Meld for editing and comparing files. Wine, WPS Office, and the input method were my desktop preferences, not AOSP build dependencies. Install what you need; the build dependencies appear below.

4. Configuring Network Access (Optional)

Use a stable source-access path for your environment. The Repo tool’s own download location and the AOSP manifest/project mirrors are separate; changing only the manifest URL may not solve every connection problem.

5. Downloading AOSP Code

The official download guide supports selecting a branch or tag with -b. This example pins android-16.0.0_r1, listed in the Android version/build table. Omitting the branch, as the old article did, does not reproduce its historical checkout.

Download repo

First try the Repo launcher supplied by the Ubuntu repositories:

1
2
3
sudo apt update
sudo apt install repo
repo version

The official guide currently requires launcher 2.4 or later. If no suitable package is available, follow the official manual installation procedure, including signature verification. The original direct download into ~/bin/repo is not retained as a complete installation recipe.

Create Working Directory

Use a new directory with sufficient free space rather than changing the branch of an existing development tree:

1
2
mkdir -p ~/aosp-16-r1
cd ~/aosp-16-r1

Initialize the Repository

1
repo init -u https://android.googlesource.com/platform/manifest -b android-16.0.0_r1

For Tsinghua’s mirror, its current instructions use https://mirrors.tuna.tsinghua.edu.cn/git/AOSP/platform/manifest. Substitute that URL for -u while keeping the same tag. Choose one initialization source; mirror lag can affect tag availability.

Sync the Code

-c narrows fetching to the manifest’s required branch/revision. The old --no-tags option affects tag fetching; it does not pin a release. Here, -j8 is an example sync concurrency level, which can be reduced for the host or network:

1
2
repo sync -c -j8
repo manifest -r -o manifest-pinned.xml

Export the manifest after a successful sync to record actual project commits. Resolve failed project syncs before building.

6. Setting Up the Build Environment and Compiling Pixel Code

The old Pixel sailfish screenshots and the new Cuttlefish example are different targets. Match the product, source, proprietary binaries, and outputs; do not combine their steps.

Install JDK

Installing openjdk-8-jdk is not a general requirement for modern AOSP. The pinned Android 16 build selects its Java toolchain, with envsetup.sh setting ANDROID_JAVA_HOME/JAVA_HOME; do not force it to use system JDK 8. Follow the relevant branch’s requirements for older versions. Building the AOSP tree is also different from building an app with Android Studio’s Gradle tooling.

Install Dependencies

For the selected Ubuntu 22.04 environment, use the official Linux package list:

1
2
3
4
sudo apt update
sudo apt install git-core gnupg flex bison build-essential zip curl \
zlib1g-dev libc6-dev-i386 x11proto-core-dev libx11-dev lib32z1-dev \
libgl1-mesa-dev libxml2-utils xsltproc unzip fontconfig python3

This corrects the old lib32z-dev name and stops carrying forward obsolete package lists such as lib32ncurses5-dev. Other distributions and older Android branches need their own matching dependencies.

Download Pixel Drivers

Historical Pixel workflow: proprietary hardware binaries must match the device codename and Android build ID. The release driver page lists those combinations. Do not combine the latest preview binaries with arbitrary source. Follow the package instructions and license terms when extracting into the corresponding source root, normally under vendor/. The original article did not record complete archive versions, so the screenshots cannot establish a matching release tag.

The historical Qualcomm extraction output is shown below:

Historical sailfish Qualcomm binary extraction

Historical sailfish Google device-file extraction

The Android 16 Cuttlefish target below does not use these sailfish binaries.

Compile the Pixel System Image

The historical interactive lunch menu and build configuration show aosp_sailfish-userdebug with the development codename Q:

Historical lunch menu

Historical sailfish build configuration

For the new Android 16 Cuttlefish example, run in one Bash session at the root of the fully synchronized source tree:

1
2
3
source build/envsetup.sh
lunch aosp_cf_x86_64_only_phone-aosp_current-userdebug
m -j8

The android-16.0.0_r1 envsetup source has removed the old interactive menu: argument-free lunch fails. The three-part selection specifies product, release configuration, and build variant. In this tag, aosp_current maps to bp2a; it does not move the checkout to today’s release. userdebug supports platform development, while production user builds do not provide the same debugging access by default.

m invokes the build, and -j8 allows up to eight parallel jobs rather than requiring exactly eight CPU threads. Reduce concurrency if memory is insufficient. A progress screenshot does not establish full build success.

Successful Compilation

After the build exits successfully, inspect the current target’s images in $ANDROID_PRODUCT_OUT. Existing files in out/ may be stale. The following screenshot remains the historical out/target/product/sailfish, not the Cuttlefish output:

Historical sailfish output directory

Before running the local Cuttlefish build, complete the host preparation: usable KVM, installed host packages, and effective group/udev configuration. Then, in the terminal retaining the build’s envsetup/lunch configuration:

1
2
launch_cvd --daemon
adb devices

If using CI downloads instead, obtain the images and cvd-host_package.tar.gz from the same build. Verify actual startup, ADB connectivity, and changed behavior; compilation alone does not establish runtime success.

7. Flashing the Device

This section requires a physical-device target with matching source, proprietary binaries, and images. Do not flash the Cuttlefish images onto a Pixel. The original instructions omitted unlocking and data-loss prerequisites.

Back up data, confirm OEM unlocking is supported, authorize USB debugging, and verify the selected product matches the phone. Follow the official Fastboot procedure to enter the bootloader and unlock if required. Unlocking erases user data and normally needs confirmation on the device; the exact procedure is model-specific.

The original fastboot devices screenshot establishes tool visibility only:

Historical fastboot device listing

In the correctly selected device build environment, the original command was:

1
fastboot flashall

The official first-flash example uses fastboot flashall -w; -w wipes /data. Omitting it does not guarantee cross-version data compatibility or prevent other steps such as unlocking from erasing data. Do not mix partition images from different devices or builds.

Historical flashall output showing writes and reboot

The screenshot records that command’s writes, not successful OS startup or functional tests. Dynamic partitions, fastbootd, AVB, and A/B slots on modern targets require their matching device procedure, not the old screenshot’s partition list.

8. Modifying and Compiling Framework, Services, and Res

Complete a full build of the same tree and target before incremental work. Directory names are not module names, and a module build does not necessarily regenerate a flashable image.

  • Java/Kotlin: Android Studio can edit the source, but AOSP is not a normal Gradle project. Use the branch’s supported project-generation tooling, such as AIDEGen, for indexing and dependencies.
  • C/C++: use a familiar editor such as VS Code with matching compilation information. Source Insight and Eclipse were historical preferences, not build requirements.

Compiling Framework

The Chinese original’s mmm framework/base was missing an s; the old directory form was mmm frameworks/base. Do not assume that old entry point applies to Android 16. The pinned tag’s installable non-APEX framework module is:

1
m framework-minus-apex

Its module definition uses the installed stem framework. A separate module named framework is build-only; its name does not make it the deployable jar. Code owned by an APEX must be built through the appropriate module.

Compiling Services

The old directory command was mmm frameworks/base/services. Android 16 provides the installable services module:

1
m services

Compiling Res

The old directory command was mmm frameworks/base/core/res. The modern module example is:

1
m framework-res

API, resource-ID, bootclasspath, APEX, or cross-partition interface changes can require dependent modules and complete images to be rebuilt. Replacing one file does not establish a correct deployment.

Root and Remount

The old successful output came from a debug build. It does not apply automatically to a production user build, and bootloader unlocking does not guarantee adb root:

Historical adb root and remount output

Android 16 debugging may use OverlayFS for a writable layer. Follow the same-tag remount instructions on a test device or virtual device configured for system modification:

1
2
3
4
5
adb root
adb remount -R
adb wait-for-device
adb root
adb remount

-R may arrange required verity-state changes and a reboot. These are debugging settings, not production-device recommendations. Resolve failures before assuming partitions are writable.

Push Changes

adb sync system updates system files from the current build output. It does not guarantee that other partitions, APEX packages, boot images, or preoptimized artifacts are updated. For a compatible, small system-file change on the same build, use separate steps:

1
2
3
4
adb shell stop
adb sync system
adb shell start
adb reboot

Check each result. If synchronization fails, restore stopped Android services with adb shell start and resolve the error. Here, stop/start controls Android services, not the terminal shell. Changes involving initialization, the bootclasspath, or other partitions need the appropriate full rebuild/deployment procedure.

After reboot, verify the actual file or version marker and test the changed function. OverlayFS overrides have OTA limitations and can remain relevant after image flashing, so confirm the effective content. Command success is only part of validation.

About Me && Blog

Below are my personal details and links. I look forward to connecting and sharing knowledge with fellow developers!

  1. About Me: Includes my WeChat and WeChat group links.
  2. Blog Navigation: A guide to the content on this blog.
  3. Curated Android Performance Articles: A collection of must-read performance optimization articles. Self-nominations/recommendations are welcome!
  4. Android Performance Knowledge Planet: The paid community stopped operating in 2026 and no longer accepts new members; this link preserves its history.

“If you want to go fast, go alone. If you want to go far, go together.”

WeChat QR Code

CATALOG
  1. 1. Recommended Hardware
  • 1. Installing Ubuntu
  • 2. Configuring Ubuntu
  • 3. Installing Essential Software
  • 4. Configuring Network Access (Optional)
  • 5. Downloading AOSP Code
    1. 1. Download repo
    2. 2. Create Working Directory
    3. 3. Initialize the Repository
    4. 4. Sync the Code
  • 6. Setting Up the Build Environment and Compiling Pixel Code
    1. 1. Install JDK
    2. 2. Install Dependencies
    3. 3. Download Pixel Drivers
    4. 4. Compile the Pixel System Image
    5. 5. Successful Compilation
  • 7. Flashing the Device
  • 8. Modifying and Compiling Framework, Services, and Res
    1. 1. Recommended IDEs
    2. 2. Compiling Framework
    3. 3. Compiling Services
    4. 4. Compiling Res
    5. 5. Root and Remount
    6. 6. Push Changes
  • About Me && Blog