Master the art of troubleshooting AOSP build failures with systematic debugging techniques and common solutions.
Building AOSP can be challenging, especially when encountering cryptic error messages and build failures. This guide provides a systematic approach to debugging AOSP build issues, from simple syntax errors to complex dependency problems.
Understanding the AOSP Build System
Build Phases
AOSP builds typically go through several phases:
- Environment Setup – Loading build configurations
- Dependency Resolution – Determining build order
- Compilation – Building individual modules
- Linking – Combining object files
- Packaging – Creating final images
Understanding these phases helps identify where issues occur.
Common Build Tools
- Soong – Modern build system using Blueprint files
- Make – Traditional build system using Makefiles
- Ninja – Build executor for faster builds
- Kati – Make-compatible build tool
Systematic Debugging Approach
1. Read the Error Message Carefully
Most build errors contain valuable information:
ninja: error: 'out/target/product/generic/system.img', needed by 'out/target/product/generic/super.img', missing and no known rule to make it
This tells us:
- Missing file:
system.img - Required by:
super.img - Problem: No rule to create it
2. Check Recent Changes
If the build was working before:
Check recent commit:
git log --oneline -10
Check modified files:
git status
git diff
3. Clean Build
Sometimes a clean build resolves issues:
Clean specific module:
make clean-<module-name>
Clean everything:
make clean
Nuclear option - delete output directory:
rm -rf out/
Common Build Issues and Solutions
1. Missing Dependencies
Error Example:
Package 'libxml2' not found
Solution:
Install missing system packages:
sudo apt-get install libxml2-dev
Or add to Android.mk:
LOCAL_SHARED_LIBRARIES += libxml2
2. Syntax Errors in Makefiles
Error Example:
Android.mk:25: *** missing separator. Stop.
Solution:
- Check line 25 for proper indentation
- Ensure tabs (not spaces) are used
- Verify variable assignments
3. Java Compilation Errors
Error Example:
error: cannot find symbol class SystemProperties
Solution:
// Add proper imports
import android.os.SystemProperties;
// Or check if class is available in current API level
4. Linker Errors
Error Example:
undefined reference to 'android_log_print'
Solution:
Add required libraries:
LOCAL_SHARED_LIBRARIES += liblog
5. SELinux Policy Errors
Error Example:
SELinux policy build failed
Solution:
Check policy syntax:
sepolicy-analyze policy.conf
# Fix policy files in sepolicy directory
Advanced Debugging Techniques
1. Verbose Build Output
Enable verbose output for more details:
Verbose make:
make -j1 showcommands
Verbose ninja:
ninja -v
2. Building Individual Modules
Build specific module:
make libril
Build with dependencies:
make libril -j1 showcommands
3. Analyzing Build Graphs
Understand dependencies:
Generate dependency graph:
make -j1 -n > build_commands.txt
Analyze specific target:
make -j1 -n system_image
4. Using Build Tools
Leverage AOSP debugging tools:
Check build configuration:
lunch # Lists available configurations
Analyze build performance:
make -j1 -O target-files-package 2>&1 | tee build.log
Memory and Disk Issues
Out of Memory Errors
Error Example:
g++: internal compiler error: Killed (program cc1plus)
Solutions:
Reduce parallel jobs:
make -j4
Add swap space:
sudo fallocate -l 8G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
Monitor memory usage:
watch -n 1 free -h
Disk Space Issues
Error Example:
No space left on device
Solutions:
Check disk usage:
df -h
Clean build cache:
make clean
Remove unused files:
find out/ -name "*.o" -delete
Environment Issues
Python Version Problems
Error Example:
/usr/bin/env: 'python': No such file or directory
Solution:
Set python symlink:
sudo ln -s /usr/bin/python3 /usr/bin/python
Or use specific Python version:
export PYTHON_PATH=/usr/bin/python3
Java Version Issues
Error Example:
Unsupported major.minor version 52.0
Solution:
Check Java version:
java -version
Set correct Java version:
export JAVA_HOME=/usr/lib/jvm/java-8-openjdk-amd64
Debugging Scripts and Tools
Build Log Analysis Script
analyze_build.sh:
#!/bin/bash
LOG_FILE="build.log"
echo "=== Build Analysis ==="
echo "Total errors: $(grep -c "error:" $LOG_FILE)"
echo "Total warnings: $(grep -c "warning:" $LOG_FILE)"
echo
echo "=== Most Common Errors ==="
grep "error:" $LOG_FILE | sort | uniq -c | sort -nr | head -5
echo
echo "=== Failed Modules ==="
grep "build failed" $LOG_FILE | awk '{print $NF}' | sort | uniq
Dependency Checker
check_deps.sh:
#!/bin/bash
MODULE=$1
if [ -z "$MODULE" ]; then
echo "Usage: $0 <module_name>"
exit 1
fi
echo "Checking dependencies for $MODULE..."
make -j1 -n $MODULE 2>&1 | grep -E "(depend|require|need)" | head -10
Best Practices for Build Debugging
1. Maintain Clean Environment
- Use separate build directories for different branches
- Regularly clean builds
- Keep source tree clean
2. Incremental Debugging
- Make small changes at a time
- Test after each change
- Use version control effectively
3. Documentation
- Document known issues and solutions
- Keep build logs for reference
- Share solutions with team
4. Testing
- Test on clean environments
- Verify on different hardware
- Use automated testing when possible
Conclusion
Debugging AOSP build issues requires patience and a systematic approach. By understanding the build system, following a structured debugging process, and using the right tools, you can efficiently resolve most build problems.
Remember that the Android build system is complex, and some issues may require deep investigation. Don't hesitate to consult the AOSP documentation, community forums, or seek expert help when needed.