Computers & Electronics
170,991 views
25 min · 3 min read
7 steps
Advanced

How to create a custom Android ROM build environment and flash a device (intermediate)

This guide walks you through setting up a reproducible Android ROM build environment and flashing a device. It assumes you know basic shell commands and have an intermediate comfort level with Linux; expect about 6–12 hours to complete your first clean build and flash cycle. Follow the steps in order and verify each checksum and command output before proceeding.

Verified by pleasexplain editors
  1. Step 1: Prepare host machine

    Install a 64-bit Linux distribution (Ubuntu 20.04/22.04 recommended) on a machine with at least 16 GB RAM, 200 GB free disk, and 8 CPU cores. Install required packages with the package manager (for example: git, openjdk-11-jdk, python3, repo, curl, unzip, build-essential, bc, zlib1g-dev) and set JAVA_HOME to the JDK path; a consistent environment prevents build failures and performance problems.

    [Illustration: Linux desktop terminal with package install commands and system specs overlay]

  2. Step 2: Get the Android source manifest

    Create a working directory (mkdir -p ~/android/rom) and init the repo using the device's manifest branch: run repo init -u <manifest_url> -b <branch> and then repo sync -j8 --no-clone-bundle, allowing several hours; syncing the right branch and branch-specific remotes ensures compatibility with device trees and vendor blobs.

    [Illustration: Terminal showing repo init command and progress bars syncing repositories across multiple threads]

  3. Step 3: Obtain device trees and vendor blobs

    Download or clone the appropriate device tree, kernel source, and vendor blobs for your device into device/, kernel/, and vendor/ directories. If proprietary blobs are required, pull them from a working device using adb pull or obtain the vendor-provided package; matching kernel and vendor versions avoids runtime crashes and bootloops.

    [Illustration: Filesystem tree showing device, kernel, and vendor folders with filenames and kernel version tag]

  4. Step 4: Configure build and local manifests

    Create or update .repo/local_manifests/roomservice.xml to include extra repos, then run repo sync -j8 again. Set up environment variables in build/envsetup.sh and choose a lunch target (source build/envsetup.sh; lunch vendor_device-userdebug). Using local manifests keeps custom changes reproducible across machines and CI.

    [Illustration: Text editor open to local_manifests XML and terminal with lunch command output]

  5. Step 5: Start the build process

    Run make -j8 or mka bacon (adjust -j to number of CPU cores + 1 up to 16) and capture the log (build.log). Expect 1–6 hours depending on hardware; resolve missing dependency errors by installing packages or syncing missing repos. A successful build produces a flashable image (e.g., boot.img, system.img, vendor.img) in out/target/product/device/.

    [Illustration: Terminal compiling Android with progress and build.log file growing in size]

  6. Step 6: Prepare device and unlock bootloader

    Enable Developer Options and USB debugging on the device, then connect via USB and run adb devices to confirm. Reboot to bootloader and use fastboot oem unlock or fastboot flashing unlock; note this wipes user data and takes about 2–5 minutes. Unlocking is required to flash custom images but increases security risks and may void warranty.

    [Illustration: Smartphone in bootloader mode connected to laptop with fastboot commands shown on screen]

  7. Step 7: Flash images and verify boot

    Use fastboot to flash images in this order: fastboot flash boot boot.img; fastboot flash system system.img; fastboot flash vendor vendor.img; then fastboot -w to wipe caches if necessary and fastboot reboot. First boot can take 2–10 minutes; monitor logs with adb logcat and ensure basic functions (Wi-Fi, telephony, sensors) come up before restoring user data.

    [Illustration: Command line flashing boot, system, vendor images to device with device booting animation on phone screen]


  • Use a separate build user account and clean environment to avoid permission issues and cross-contamination.
  • Use ccache with roughly 50–200 GB allocated to speed incremental builds; set CCACHE_DIR and CCACHE_MAXSIZE before building.
  • Keep a copy of vendor blobs and prebuilts in an archive (tar.gz) so you can reproduce builds in 30–60 minutes instead of hours.
  • Automate repeatable steps with a shell script that runs repo sync, env setup, and mka -j; log stdout/stderr to timestamped files.
  • Take a full NANDroid backup or use provider-specific backup tools before unlocking or flashing; verify backup integrity (SHA256) and store off-device.
  • Test builds on a secondary device first; maintain a device-specific checklist of known-working kernel and vendor versions to reduce debugging time.

  • Unlocking the bootloader will factory-reset the device and erase all user data; back up important data before proceeding.
  • Flashing incompatible images can brick the device; verify device codename, image checksums (SHA256), and build branch before flashing.
  • Distributing ROMs with proprietary blobs may violate license terms; confirm licensing and redistribution rights before publishing.
  • Incorrect use of fastboot or interrupts during flashing can leave the device in an unbootable state; ensure stable power and do not disconnect USB during flash operations.

Was this guide helpful?