Technical review — 2026-10-13: This is a historical Nexus 5 / Android Lollipop tutorial with an obsolete device and toolchain. Its LRX22C binaries correspond to Android 5.0.1 / AOSP
android-5.0.1_r1. The source, binary, and flashing requirements below are tied to that combination. An Android 16 Cuttlefish example is added separately; do not mix it with the old phone firmware.
Following my previous article, Using Android Studio to View Android Lollipop Source Code, we know that simply reading code has its limits—understanding can remain superficial and easily forgotten. In contrast, code you’ve personally written or modified tends to leave a much deeper impression, and the process becomes easier to grasp during the implementation phase. While studying the source code, being able to modify it, run it on a phone, and see the results firsthand significantly boosts both learning efficiency and enthusiasm. This article explains how to compile the Android Lollipop source code yourself and run it on a Nexus 5.
Why compile your own firmware instead of using Google’s factory images?
The goal here is a userdebug build suitable for platform debugging. User builds restrict facilities such as ADB root. Userdebug enables more debugging operations, but does not make every partition freely writable under all conditions.
This guide assumes a consistent Lollipop source tree and a Nexus 5. See the historical AOSP environment guide and source download instructions. Android 5.x uses OpenJDK 7 on Linux. Keep its old OS and dependencies in a dedicated historical build environment rather than using it as the setup for a current workstation.
AOSP means Android Open Source Project. It includes the platform and open-source apps, but not the proprietary Google Mobile Services (GMS) suite. Hardware binaries, GMS licensing, and Android compatibility are separate matters. Meeting the CDD and passing CTS establishes compatibility; it does not automatically grant GMS. For the requirements, see the Android compatibility overview.
A Current Learning Path: Android 16 Cuttlefish
For changing system code and observing its behavior, start with a Cuttlefish virtual device. This example pins the source to android-16.0.0_r1. Use a separate new directory on a host meeting the Linux build requirements:
1 | repo init --partial-clone -b android-16.0.0_r1 -u https://android.googlesource.com/platform/manifest |
The product is defined in that tag’s Cuttlefish configuration, and its release map maps aosp_current to bp2a. Launching also requires the host packages, KVM, and group setup described in the Cuttlefish launch instructions; a successful m does not start the virtual device.
The official getting-started guide uses the moving android-latest-release branch. Record the actual manifest for reproducibility. For a physical device, verify the device tree, vendor binaries, bootloader, and baseband for each release. An old Pixel or Nexus entry on the download page does not imply support for every new Android version.
1. Initializing the Build Environment — Android 5.0.1
Return to the legacy Nexus 5 workspace. The AOSP build table maps LRX22C to android-5.0.1_r1. Confirm that the source tree consistently uses this version, then run from the source root:
1 | source build/envsetup.sh |
2. Choosing the Target
The old branch supports the interactive lunch menu. Selecting the target directly avoids depending on a menu number:
1 | lunch aosp_hammerhead-userdebug |
3. Checking the Device and Build Variant
3.1 The Target Used Here
| Device | Device codename | Android 5.0.1 build target |
|---|---|---|
| Nexus 5 (GSM/LTE) | hammerhead | aosp_hammerhead-userdebug |
The original multi-device table mixed product names and targets from different eras. Check product definitions in the selected source tree for other devices instead of merely replacing hammerhead with another codename.
3.2 Build Variants
| Variant | Purpose |
|---|---|
user |
Production configuration with restricted debugging access |
userdebug |
Similar to user, with additional facilities such as root debugging for platform development |
eng |
Engineering configuration with more debugging behavior; not a direct proxy for production performance |
The relevant configuration values for this example are:
1 | PLATFORM_VERSION=5.0.1 |
Use the version defined by the selected source tag. TARGET_BUILD_TYPE=release can coexist with TARGET_BUILD_VARIANT=userdebug; they are different settings.
4. Setting Up Proprietary Binaries
Use the hammerhead / LRX22C section of Google’s binary download page. These packages provide hardware support missing from the open-source tree; they are not workstation USB drivers. The SHA-256 values below are published by Google.
| Hardware component | Company | Download |
|---|---|---|
| NFC, Bluetooth, Wi-Fi | Broadcom | LRX22C |
| Camera, Sensors, Audio | LG | LRX22C |
| Graphics, GSM, Camera, GPS, Sensors, Media, DSP, USB | Qualcomm | LRX22C |
Official SHA-256 values:
1 | broadcom-hammerhead-lrx22c-964d941e.tgz |
Check downloaded files against the official checksums. Extract each archive, read its license and instructions, then run its extraction script from the source root and complete the license prompts. The files go under vendor/. Each supplier’s package has a distinct role; duplicating the LG package does not replace Qualcomm’s, and binaries from different build IDs should not be mixed.
5. Starting the Build
1 | make -j8 |
-j8 is the original concurrency example; adjust it for CPU, memory, and observed build behavior. The full build must exit successfully and produce the required files under out/target/product/hammerhead/. A message saying system.img was generated does not prove the whole build succeeded.
The build takes a while. These lines come from my build log at the time and show the system-image stage:
1 | Installed file list: out/target/product/hammerhead/installed-files.txt |
6. Flashing the Firmware
Unlocking the bootloader and flashing with -w both erase user data. Back up first, confirm the device is a Nexus 5 / hammerhead, and verify that the build artifacts, bootloader, and baseband match the intended build.
If Android is running and ADB is authorized, use adb reboot bootloader to enter bootloader / fastboot mode. For powered-off devices, consult the official key-combination table; it lists both volume buttons and Power for Nexus 5. This is fastboot mode, not recovery.
Check the connection and product name:
1 | fastboot devices |
If still locked, a pre-2015 device such as Nexus 5 uses fastboot oem unlock, followed by on-device confirmation to erase data and unlock. Do not substitute the later fastboot flashing unlock workflow. See the official Fastboot instructions.
In the same terminal where envsetup and lunch aosp_hammerhead-userdebug were run, confirm that ANDROID_PRODUCT_OUT points to this build’s hammerhead artifacts, then use the original flashing command:
1 | echo "$ANDROID_PRODUCT_OUT" |
The historical fastboot implementation reads android-info.txt and images from the product output directory. Merely changing to the source root does not initialize that environment. With multiple devices connected, use -s DEVICE_SERIAL consistently for all fastboot operations.
My flash log from that run ended with rebooting... and finished. total time: 70.095s. After flashing, check normal boot and the required Wi-Fi, camera, audio, and other functions. Fastboot success or a visible launcher alone does not prove all vendor components match.
7. The Original Desktop Screenshot
And here was the desktop, finally.

About Me && Blog
Below are my personal details and links. I look forward to connecting and sharing knowledge with fellow developers!
- About Me: Includes my WeChat and WeChat group links.
- Blog Navigation: A guide to the content on this blog.
- Curated Android Performance Articles: A collection of must-read performance optimization articles. Self-nominations/recommendations are welcome!
- 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.”
