Learn industry best practices for custom ROM development and how to avoid common mistakes that can break your builds or devices.
Developing custom ROMs is both an art and a science. While AOSP provides the foundation, creating a stable, feature-rich custom ROM requires careful attention to detail and adherence to best practices. In this guide, we'll explore the most important practices and common pitfalls to avoid.
Project Structure and Organization
Directory Structure
Organize your project with a clear, logical structure:
custom_rom/
├── device/
│ └── manufacturer/
│ └── device_name/
├── vendor/
│ └── manufacturer/
│ └── device_name/
├── kernel/
│ └── manufacturer/
│ └── device_name/
└── patches/
├── frameworks/
├── packages/
└── system/
Version Control Best Practices
- Use Git Flow: Implement a branching strategy
- Commit Often: Make small, logical commits
- Write Descriptive Messages: Include what and why
- Tag Releases: Use semantic versioning
Device Tree Configuration
Essential Files
Every device tree should include:
AndroidProducts.mk: Product definitionBoardConfig.mk: Board-specific configurationdevice.mk: Device-specific makefileslineage.mkoraosp.mk: ROM-specific configuration
BoardConfig.mk Best Practices
Always specify target architecture:
TARGET_ARCH := arm64
TARGET_ARCH_VARIANT := armv8-a
TARGET_CPU_ABI := arm64-v8a
Bootloader and recovery:
TARGET_BOOTLOADER_BOARD_NAME := device_name
TARGET_NO_BOOTLOADER := true
TARGET_NO_RADIOIMAGE := true
Kernel configuration:
BOARD_KERNEL_CMDLINE := console=ttyMSM0,115200,n8 androidboot.console=ttyMSM0
BOARD_KERNEL_BASE := 0x80000000
BOARD_KERNEL_PAGESIZE := 4096
Security Considerations
SELinux Policies
Never use permissive SELinux in production:
Bad practice:
BOARD_KERNEL_CMDLINE += androidboot.selinux=permissive
Good practice - fix policies instead:
BOARD_SEPOLICY_DIRS += device/manufacturer/device_name/sepolicy
Verified Boot
Implement proper verified boot when possible:
BOARD_AVB_ENABLE := true
BOARD_AVB_MAKE_VBMETA_IMAGE_ARGS += --flags 3
Performance Optimization
Compiler Optimizations
Enable optimizations:
USE_O3_OPTIMIZATIONS := true
ENABLE_OPTIMIZATIONS := true
Target-specific optimizations:
TARGET_CPU_VARIANT := cortex-a53
TARGET_2ND_CPU_VARIANT := cortex-a53
Memory Management
Optimize for device RAM:
PRODUCT_PROPERTY_OVERRIDES += \
ro.config.low_ram=false \
ro.config.zram=true
Common Pitfalls to Avoid
1. Ignoring Dependencies
Always check and include all required dependencies:
In device.mk:
PRODUCT_PACKAGES += \
libril \
libbinder \
libutils
2. Hardcoded Values
Avoid hardcoding device-specific values:
Bad:
BOARD_KERNEL_CMDLINE += androidboot.serialno=123456789
Good:
BOARD_KERNEL_CMDLINE += androidboot.serialno=$(shell cat /proc/cmdline | grep -o 'androidboot.serialno=[^ ]*' | cut -d= -f2)
3. Copying Without Understanding
Don't blindly copy configurations from other devices. Understand what each setting does.
4. Skipping Testing
Test thoroughly on actual hardware:
- Basic functionality (calls, SMS, data)
- Hardware features (camera, GPS, sensors)
- Performance benchmarks
- Battery life tests
Build System Optimization
Parallel Builds
Optimize build times:
Use all available cores:
make -j$(nproc)
Or limit if running out of memory:
make -j$(($(nproc) / 2))
ccache Configuration
Enable ccache for faster rebuilds:
export USE_CCACHE=1
export CCACHE_DIR=/path/to/ccache
ccache -M 50G
Quality Assurance
Automated Testing
Implement automated testing:
Build test script:
#!/bin/bash
make clean
make -j$(nproc) 2>&1 | tee build.log
if [ $? -eq 0 ]; then
echo "Build successful"
else
echo "Build failed"
exit 1
fi
Code Review Process
- Review All Changes: Don't commit untested code
- Test on Hardware: Emulator testing isn't enough
- Document Changes: Maintain a changelog
- Peer Review: Have others review your code
Maintenance and Updates
Regular Updates
Keep your ROM updated:
- Security Patches: Monthly security updates
- Bug Fixes: Address reported issues promptly
- Feature Updates: Add new features carefully
- Upstream Merges: Regularly merge upstream changes
User Support
Provide good user support:
- Clear installation instructions
- Troubleshooting guides
- Bug reporting templates
- Active community support
Documentation
Essential Documentation
Always document:
- Build instructions
- Installation procedures
- Known issues
- Feature list
- Changelog
Example Build Instructions
Create comprehensive build instructions that include:
- Prerequisites and system requirements
- Step-by-step build process
- Troubleshooting common issues
- Installation and flashing procedures
Conclusion
Custom ROM development requires patience, attention to detail, and continuous learning. By following these best practices and avoiding common pitfalls, you'll create more stable, secure, and maintainable ROMs.
Remember that the Android ecosystem is constantly evolving, so stay updated with the latest changes and best practices in the AOSP community.