
Android Build
- 4 installs
- 30 repo stars
- Updated January 28, 2026
- hyperb1iss/android-skill
Builds Android apps via Gradle CLI and custom ROMs via AOSP/LineageOS, covering build variants, APK/AAB outputs, and device-tree/kernel builds.
About
Covers building Android apps with Gradle and custom ROMs with AOSP/LineageOS. A developer uses it when running gradle assemble, building an APK/AAB, or compiling an Android ROM with lunch/mka.
- Essential Gradle tasks and APK/AAB output paths
- AOSP and LineageOS ROM build commands
Android Build by the numbers
- 4 all-time installs (skills.sh)
- Ranked #874 of 1,039 Mobile Development skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/hyperb1iss/android-skill --skill android-buildAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 4 |
|---|---|
| repo stars | ★ 30 |
| Last updated | January 28, 2026 |
| Repository | hyperb1iss/android-skill ↗ |
What it does
Builds Android apps via Gradle CLI and custom ROMs via AOSP/LineageOS, covering build variants, APK/AAB outputs, and device-tree/kernel builds.
Files
Android Build Systems
This skill covers building Android apps via Gradle CLI and building custom ROMs via AOSP/LineageOS.
---
App Building (Gradle CLI)
Essential Commands
./gradlew tasks # List available tasks
./gradlew assembleDebug # Build debug APK
./gradlew assembleRelease # Build release APK
./gradlew installDebug # Build + install to device
./gradlew bundleRelease # Build AAB (App Bundle)
# APK output location
# app/build/outputs/apk/debug/app-debug.apk
# app/build/outputs/apk/release/app-release.apkBuild Variants
./gradlew assembleFreeDebug # Flavor + build type
./gradlew assemblePaidRelease
./gradlew assembleDebug --info # Verbose output
./gradlew assembleRelease -x test # Skip testsTesting
./gradlew test # Unit tests
./gradlew testDebugUnitTest # Debug unit tests only
./gradlew connectedAndroidTest # Instrumented tests
./gradlew connectedCheck # All connected tests
# Run specific test
./gradlew test --tests "*.MyTestClass"Linting & Analysis
./gradlew lint # Run lint
./gradlew lintDebug # Debug only (faster)
./gradlew ktlintCheck # Kotlin style (if configured)
./gradlew detekt # Detekt analysis (if configured)Clean & Refresh
./gradlew clean # Clean build
./gradlew clean assembleDebug # Clean + build
./gradlew --refresh-dependencies # Force dependency refresh
./gradlew --stop # Stop Gradle daemonDependencies
./gradlew dependencies # All dependencies
./gradlew app:dependencies # Module dependencies
./gradlew dependencyInsight --dependency <name>Signing
Debug keystore location:
- Linux:
~/.android/debug.keystore - macOS:
~/.android/debug.keystore - Windows:
C:\Users\<user>\.android\debug.keystore
Password: android, Alias: androiddebugkey
# Create release keystore
keytool -genkey -v -keystore release.keystore \
-alias my-key-alias -keyalg RSA -keysize 2048 -validity 10000Performance
./gradlew assembleDebug --parallel # Parallel builds
./gradlew assembleDebug --build-cache # Use cache
./gradlew assembleDebug --offline # Offline mode
./gradlew --scan # Build scan (uploads data)
./gradlew --profile # Local profile reportgradle.properties Optimization
org.gradle.jvmargs=-Xmx4g -XX:+HeapDumpOnOutOfMemoryError
org.gradle.parallel=true
org.gradle.caching=true
org.gradle.configuration-cache=true
android.useAndroidX=true---
SDK Management
sdkmanager
sdkmanager --list # List available packages
sdkmanager --list | grep system # Filter system images
sdkmanager "platform-tools" # Install package
sdkmanager "platforms;android-34" # Install platform
sdkmanager "system-images;android-34;google_apis;x86_64"
sdkmanager --update # Update all
sdkmanager --licenses # Accept licensesavdmanager
avdmanager list device # List device profiles
avdmanager list avd # List created AVDs
# Create AVD
avdmanager create avd -n my_avd \
-k "system-images;android-34;google_apis;x86_64" \
-d pixel_6
avdmanager delete avd -n my_avdEmulator CLI
emulator -list-avds # List AVDs
emulator @my_avd # Start AVD
emulator @my_avd -no-snapshot # Fresh boot
emulator @my_avd -no-window # Headless
emulator @my_avd -wipe-data # Factory reset---
ROM Building (AOSP/LineageOS)
Environment Setup
# Install repo tool
mkdir -p ~/.bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo
chmod a+x ~/.bin/repo
export PATH="$HOME/.bin:$PATH"
# Initialize repo
mkdir android && cd android
repo init -u https://github.com/LineageOS/android.git -b lineage-21.0
# Or AOSP: repo init -u https://android.googlesource.com/platform/manifest
# Sync source
repo sync -c -j$(nproc) --force-sync --no-tags --no-clone-bundleBuild Commands
# Setup environment
source build/envsetup.sh
# Select device
lunch <device>-userdebug # AOSP
breakfast <device> # LineageOS
# Build
m # Full build
mka bacon # LineageOS (with flashable zip)
mka bootimage # Just boot.img
mka systemimage # Just system
# Parallel build
m -j$(nproc)Build Variants
| Variant | Purpose |
|---|---|
user | Production, no root, limited debugging |
userdebug | Like user + root + debugging |
eng | Development, all debug tools |
Common Targets
m bootimage # Kernel + ramdisk
m systemimage # System partition
m vendorimage # Vendor partition
m otapackage # OTA zip
mka bacon # LineageOS flashable zip
# Module-specific
m Settings # Just Settings app
mm # Build current directory
mmm packages/apps/Settings # Build specific pathLineageOS Specifics
breakfast <device> # Setup + sync device deps
brunch <device> # breakfast + mka bacon
# Cherry-pick from Gerrit
repopick <change_number>
repopick -t <topic>
# Sync specific project
repo sync packages/apps/SettingsBuild Output
out/target/product/<device>/
├── boot.img # Kernel + ramdisk
├── system.img # System partition
├── vendor.img # Vendor partition
├── lineage-*.zip # Flashable zip (LineageOS)
└── recovery.img # Recovery (non-A/B)---
Device Trees
Structure
device/<vendor>/<device>/
├── AndroidProducts.mk # Product makefiles list
├── BoardConfig.mk # Board configuration
├── device.mk # Device makefile
├── lineage_<device>.mk # LineageOS product
├── extract-files.sh # Vendor blob extraction
├── proprietary-files.txt # Blob list
├── sepolicy/ # SELinux policies
└── overlay/ # Resource overlaysKey Files
BoardConfig.mk - Hardware configuration:
TARGET_ARCH := arm64
TARGET_BOARD_PLATFORM := <platform>
TARGET_BOOTLOADER_BOARD_NAME := <device>
BOARD_KERNEL_CMDLINE := ...
BOARD_BOOT_HEADER_VERSION := 4device.mk - Device packages:
PRODUCT_PACKAGES += \
android.hardware.audio@7.0-impl \
audio.primary.$(TARGET_BOARD_PLATFORM)
PRODUCT_COPY_FILES += \
$(LOCAL_PATH)/configs/audio_policy.conf:...---
Kernel Building
Standalone
# Setup
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
# Or for Clang:
export CC=clang
export CLANG_TRIPLE=aarch64-linux-gnu-
# Configure
make <device>_defconfig
# Build
make -j$(nproc)
# Output
arch/arm64/boot/Image.gzIn AOSP Tree
# In BoardConfig.mk
TARGET_KERNEL_SOURCE := kernel/<vendor>/<device>
TARGET_KERNEL_CONFIG := <device>_defconfig
TARGET_KERNEL_CLANG_COMPILE := true---
Troubleshooting
Common Gradle Issues
# OOM
export GRADLE_OPTS="-Xmx4g"
# Daemon issues
./gradlew --stop
rm -rf ~/.gradle/daemon
# Cache issues
./gradlew clean --refresh-dependenciesCommon AOSP Issues
# Ninja error - usually dependency issue
m clean && m
# Jack server (old builds)
./prebuilts/sdk/tools/jack-admin kill-server
./prebuilts/sdk/tools/jack-admin start-server
# SELinux issues
audit2allow -i audit.logBuild Logs
# Gradle
./gradlew assembleDebug --stacktrace
./gradlew assembleDebug --info
# AOSP
m 2>&1 | tee build.log---
Quick Reference
Gradle
| Task | Command |
|---|---|
| Build debug | ./gradlew assembleDebug |
| Build release | ./gradlew assembleRelease |
| Install | ./gradlew installDebug |
| Test | ./gradlew test |
| Lint | ./gradlew lint |
| Clean | ./gradlew clean |
| Dependencies | ./gradlew dependencies |
AOSP/LineageOS
| Task | Command |
|---|---|
| Setup env | source build/envsetup.sh |
| Select device | lunch <device>-userdebug |
| Full build | m |
| LineageOS zip | mka bacon |
| Just boot | mka bootimage |
| Sync | repo sync -c -j$(nproc) |
AOSP Build System Deep Dive
Environment Setup
System Requirements
- Ubuntu 20.04+ or compatible
- 400GB+ free disk space
- 32GB+ RAM recommended
- Fast internet for initial sync
Dependencies
sudo apt-get install git-core gnupg flex bison build-essential \
zip curl zlib1g-dev libc6-dev-i386 libncurses5 \
x11proto-core-dev libx11-dev lib32z1-dev libgl1-mesa-dev \
libxml2-utils xsltproc unzip fontconfig python3Repo Tool
mkdir -p ~/.bin
curl https://storage.googleapis.com/git-repo-downloads/repo > ~/.bin/repo
chmod a+x ~/.bin/repo
export PATH="$HOME/.bin:$PATH"---
Source Management
Initialize
# AOSP
repo init -u https://android.googlesource.com/platform/manifest -b android-14.0.0_r1
# LineageOS
repo init -u https://github.com/LineageOS/android.git -b lineage-21.0Sync
repo sync -c -j$(nproc) --force-sync --no-tags --no-clone-bundle
# Options:
# -c Current branch only
# -j$(nproc) Parallel jobs
# --force-sync Force overwrite
# --no-tags Skip tags (faster)
# --no-clone-bundle Don't use bundlesLocal Manifests
Create .repo/local_manifests/ for custom repos:
<?xml version="1.0" encoding="UTF-8"?>
<manifest>
<remote name="github" fetch="https://github.com/" />
<project name="user/device_vendor_device"
path="device/vendor/device"
remote="github"
revision="lineage-21" />
</manifest>---
Build System Architecture
Make vs Soong
- Make (
.mkfiles): Legacy, still used for device trees - Soong (
Android.bp): Modern, Go-based, for most modules - Blueprint: DSL for
Android.bpfiles - Ninja: Actual build executor
Build Flow
1. source build/envsetup.sh - Load functions 2. lunch <target> - Set build variables 3. m - Invoke Soong/Make → Ninja → Build
---
envsetup.sh Functions
source build/envsetup.sh
# Essential
lunch <target> # Set target device
m # Build (Soong-based)
mm # Build current directory
mmm <path> # Build specific path
mma # mm + dependencies
mmma <path> # mmm + dependencies
# LineageOS additions
breakfast <device> # Setup + device deps
brunch <device> # breakfast + mka bacon
eat # Alias for brunch
# Utilities
croot # cd to top of tree
godir <file> # Find and go to file
mgrep <pattern> # Grep makefiles
cgrep <pattern> # Grep C/C++
jgrep <pattern> # Grep Java---
lunch Targets
Format: <product>-<variant>
lunch aosp_crosshatch-userdebug # Pixel 3 XL
lunch lineage_cheeseburger-userdebug # OnePlus 5Variants
| Variant | Root | Debug | Use Case |
|---|---|---|---|
| user | No | No | Production |
| userdebug | Yes | Yes | Development (most common) |
| eng | Yes | Full | Engineering/testing |
---
Build Targets
Full Builds
m # Full build
m dist # Full + distribution packages
mka bacon # LineageOS flashable zip
mka otapackage # OTA packageImage Targets
mka bootimage # boot.img
mka systemimage # system.img
mka vendorimage # vendor.img
mka recoveryimage # recovery.img (non-A/B)
mka superimage # super.img (dynamic)Module Targets
m Settings # Build Settings app
m libstagefright # Build specific library
m android.hardware.audio@7.0-impl---
Device Tree Structure
device/<vendor>/<device>/
├── Android.mk # Legacy make
├── Android.bp # Soong build
├── AndroidProducts.mk # Product list
├── BoardConfig.mk # Board hardware
├── device.mk # Device packages
├── lineage_<device>.mk # LineageOS product
├── vendorsetup.sh # Add to lunch
├── extract-files.sh # Blob extraction
├── proprietary-files.txt # Blob list
├── sepolicy/ # SELinux
│ ├── file_contexts
│ ├── property_contexts
│ └── *.te
├── overlay/ # Resource overlays
├── configs/ # Config files
├── rootdir/ # Init files
└── recovery/ # Recovery configBoardConfig.mk Key Variables
# Architecture
TARGET_ARCH := arm64
TARGET_ARCH_VARIANT := armv8-2a
TARGET_CPU_ABI := arm64-v8a
# Platform
TARGET_BOARD_PLATFORM := sm8350
TARGET_BOOTLOADER_BOARD_NAME := lahaina
# Kernel
TARGET_KERNEL_SOURCE := kernel/oneplus/sm8350
TARGET_KERNEL_CONFIG := vendor/lahaina-qgki_defconfig
TARGET_KERNEL_CLANG_COMPILE := true
BOARD_KERNEL_CMDLINE := androidboot.hardware=qcom
# Boot image
BOARD_BOOT_HEADER_VERSION := 3
BOARD_KERNEL_PAGESIZE := 4096
BOARD_RAMDISK_USE_LZ4 := true
# Partitions
BOARD_SUPER_PARTITION_SIZE := 9126805504
BOARD_SYSTEMIMAGE_FILE_SYSTEM_TYPE := ext4
# Recovery
TARGET_RECOVERY_FSTAB := $(DEVICE_PATH)/rootdir/etc/fstab.qcom
TARGET_RECOVERY_PIXEL_FORMAT := RGBX_8888
# SELinux
BOARD_VENDOR_SEPOLICY_DIRS += $(DEVICE_PATH)/sepolicy/vendor---
Kernel Building
In-Tree
# BoardConfig.mk
TARGET_KERNEL_SOURCE := kernel/vendor/device
TARGET_KERNEL_CONFIG := device_defconfig
TARGET_KERNEL_CLANG_COMPILE := true
# GKI (Android 12+)
TARGET_KERNEL_CLANG_VERSION := r416183b
BOARD_USES_GENERIC_KERNEL_IMAGE := trueStandalone
cd kernel/vendor/device
# Setup
export ARCH=arm64
export CROSS_COMPILE=aarch64-linux-gnu-
# Or Clang:
export CC=clang
export CLANG_TRIPLE=aarch64-linux-gnu-
# Build
make device_defconfig
make -j$(nproc)
# Output
ls arch/arm64/boot/Image*---
Vendor Blobs
proprietary-files.txt Format
# Audio
vendor/lib64/hw/audio.primary.lahaina.so
vendor/etc/audio_policy_configuration.xml
# With source path
vendor/lib64/libqti-perfd-client.so:vendor/lib64/libqti-perfd-client.so
# Pinned (hash required)
-vendor/app/TimeService/TimeService.apk
# From other device
vendor/lib64/lib.so|device/otherExtraction
./extract-files.sh # From device
./extract-files.sh ~/ota.zip # From OTA---
SELinux/SEAndroid
Common Files
sepolicy/
├── file_contexts # File labels
├── property_contexts # Property labels
├── hwservice_contexts # HAL service labels
├── genfs_contexts # Generated FS labels
└── vendor/*.te # Policy rulesDebugging
# Check mode
adb shell getenforce
# Set permissive (temporary, needs root)
adb shell su -c "setenforce 0"
# Find denials
adb shell dmesg | grep "avc: denied"
adb logcat | grep "avc: denied"
# Generate policy
audit2allow -i audit.log---
Common Issues
Out of Memory
export JACK_SERVER_VM_ARGUMENTS="-Xmx8g"
export _JAVA_OPTIONS="-Xmx8g"Ninja Build Error
# Usually dependency issue, clean and rebuild
m clean
mMissing Blobs
Check logcat for:
E ServiceManager: Could not find service <name>
E linker: cannot find symbolSolution: Add missing blobs to proprietary-files.txt
---
Useful Commands
# Find module name from file
grep -r "LOCAL_MODULE := " --include="*.mk" | grep <filename>
# Find Android.bp module
grep -r "name: " --include="*.bp" | grep <name>
# Check what builds a file
mgrep <filename>
# Incremental build specific module
mm <module>
# Force rebuild
touch <file> && mmLineageOS Development Reference
LineageOS-Specific Commands
breakfast
Setup device and sync dependencies:
source build/envsetup.sh
breakfast <device>
# Example:
breakfast cheeseburger # OnePlus 5
breakfast oriole # Pixel 6This will:
1. Set up lunch target 2. Sync device-specific repos 3. Sync kernel and vendor repos
brunch
Full build shortcut (breakfast + build):
brunch <device>
# Equivalent to:
# breakfast <device>
# mka baconmka bacon
Build flashable ZIP:
mka bacon
# Output: out/target/product/<device>/lineage-21.0-*-UNOFFICIAL-<device>.zip---
Directory Structure
vendor/lineage
vendor/lineage/
├── build/
│ ├── core/ # Build system extensions
│ ├── soong/ # Soong config modules
│ └── tools/ # Build scripts
├── config/
│ ├── common.mk # Common packages
│ ├── BoardConfigLineage.mk
│ └── version.mk # Version info
├── overlay/ # System overlays
├── prebuilt/ # Prebuilt apps
└── sepolicy/ # SELinux additionslineage-sdk
lineage-sdk/
├── sdk/ # SDK source
├── api/ # API definitions
└── samples/ # Example code---
Device Tree for LineageOS
Required Files
device/<vendor>/<device>/
├── lineage_<device>.mk # Product makefile
├── lineage.dependencies # Repo dependencies
└── vendorsetup.sh # Add to lunch menulineage\_<device>.mk
# Inherit from device
$(call inherit-product, device/vendor/device/device.mk)
# Inherit LineageOS product
$(call inherit-product, vendor/lineage/config/common_full_phone.mk)
# Device identifier
PRODUCT_NAME := lineage_device
PRODUCT_DEVICE := device
PRODUCT_BRAND := Vendor
PRODUCT_MODEL := Device Name
PRODUCT_MANUFACTURER := Vendor
PRODUCT_GMS_CLIENTID_BASE := android-vendor
PRODUCT_BUILD_PROP_OVERRIDES += \
PRIVATE_BUILD_DESC="device-user 13 ..."
BUILD_FINGERPRINT := vendor/device/device:13/...lineage.dependencies
[
{
"repository": "android_kernel_vendor_device",
"target_path": "kernel/vendor/device"
},
{
"repository": "android_device_vendor_device-common",
"target_path": "device/vendor/device-common"
},
{
"repository": "proprietary_vendor_device",
"target_path": "vendor/device"
}
]---
repopick
Cherry-pick changes from Gerrit:
# Single change
repopick 12345
# Multiple changes
repopick 12345 12346 12347
# By topic
repopick -t feature-name
# With dependencies
repopick -Q 12345
# Force (overwrite local changes)
repopick -f 12345Finding Changes
1. Go to review.lineageos.org 2. Find change number in URL 3. repopick <number>
---
LineageOS Features
Trust Interface
Security dashboard in Settings:
<!-- overlay -->
<bool name="config_enableTrustInterface">true</bool>LiveDisplay
Display color management:
# device.mk
PRODUCT_PACKAGES += \
lineage.livedisplay@2.0-service-sdmStyles
System-wide theming:
PRODUCT_PACKAGES += \
LineageThemesStubProtected Apps
App hiding feature:
PRODUCT_PACKAGES += \
LineageParts---
Building Kernels for LineageOS
In-Tree (Recommended)
# BoardConfig.mk
TARGET_KERNEL_SOURCE := kernel/vendor/device
TARGET_KERNEL_CONFIG := lineageos_device_defconfig
TARGET_KERNEL_CLANG_COMPILE := true
# Clang version (from prebuilts)
TARGET_KERNEL_CLANG_VERSION := r416183bPrebuilt
# BoardConfig.mk
TARGET_PREBUILT_KERNEL := device/vendor/device/prebuilt/kernel
BOARD_KERNEL_IMAGE_NAME := Image---
Contributing to LineageOS
Gerrit Workflow
# Setup
git config --global review.review.lineageos.org.username <your_username>
# Create branch
repo start my_feature .
# Make changes
git add .
git commit -m "subsystem: Description of change"
# Push for review
git push ssh://<username>@review.lineageos.org:29418/<project> HEAD:refs/for/<branch>Commit Message Format
subsystem: Short description
Longer explanation if needed. Wrap at 72 characters.
Change-Id: I1234567890abcdef...Code Style
- Follow Android code style
- 4-space indentation (no tabs)
- 100-character line limit
- No trailing whitespace
---
Upstream Merging
aosp-merger
Merge AOSP tags:
cd vendor/lineage/build/tools
./aosp-merger.sh <tag>
# Example: ./aosp-merger.sh android-14.0.0_r20Manual Merge
cd frameworks/base
git fetch aosp
git merge android-14.0.0_r20
# Resolve conflicts
git mergetool
git add .
git commit---
Common Issues
Missing Dependencies
# Re-run breakfast to sync
breakfast <device>
# Or manual sync
repo sync device/vendor/device
repo sync kernel/vendor/deviceSELinux Denials
# Get denials
adb shell dmesg | grep "avc: denied"
# Generate policy
adb shell dmesg | grep "avc: denied" | audit2allowBuild Signature Mismatch
# Clean vendor
rm -rf out/target/product/<device>/vendor
m vendorimage---
Quick Reference
| Task | Command |
|---|---|
| Setup device | breakfast <device> |
| Full build | brunch <device> |
| Build ZIP | mka bacon |
| Cherry-pick | repopick <number> |
| Sync all | repo sync |
| Sync device | repo sync device/vendor/device |
| Clean build | m clean && brunch <device> |