前段时间下载了 Android10 和 11 源码,现在准备编译一个镜像出来试试。人生的意义,在于折腾不止
更新:用同样的方法编译 Android 11 成功
系统准备
编译Android 10 最低要求
- ubuntu18 虚拟机
- 内存:8G
- swap:8G
如果是编译 Android 11 ,则最低要求为(之前尝试使用8G内存编译,无论如何设置都会导致OOM):
- 内存:12G
- swap:16G
Android 源码百度网盘打包下载 包含了Android 1.6 到 最新的 Android 11,且持续更新
依赖
安装依赖
sudo apt-get update
sudo apt-get install python openjdk-8-jdk make bison g++-multilib gcc-multilib lib32ncurses5-dev lib32z1-dev libxml2-utils
编译 Android10 或者 Android 11
将源码解压
如果是 7z
格式压缩包,使用命令 7z x android-10.0.0_r41.7z.001
解压
如果是 tar.gz
格式压缩包,使用命令 tar -zxvf xxxxxx.tar.gz
解压
如果没有 7z 命令,需要安装 sudo apt-get install p7zip-full
然后进入解压后的源码目录,设定内存使用限制(防止 OutOfMemery):
如果是在编译Android7,使用的是:export JACK_SERVER_VM_ARGUMENTS
编译Android 10需要使用如下参数设定内存限制:
export _JAVA_OPTIONS="-Xmx4g"
更新:如果编译的是Android 11 ,内存限制要为 8G,使用 4G 无法编译,而且也要将swap 调整为 16G
export _JAVA_OPTIONS="-Xmx8g"
这个参数是java 的环境变量,会作用到所有java进程
所以不仅限于编译Android源码,如果运行某些java程序,出现了内存溢出,同样可以使用这个环境变量限定内存使用
执行命令,选择编译的系统类型:
source build/envsetup.sh
lunch
在执行 lunch
时,会显示一个列表,根据需要选择自己要编译的系统类型,一般是 x86_64-eng
然后执行命令: make -j2
可以自定义编译线程,将 -j2
换成 -j4
或者更多线程数,根据自己电脑CPU核心来选择
这一步要非常久,等编译好了即可
在编译过程中,进程有过异常退出,没有报错直接 kill 的。再次调用
make
编译,最终显示成功
编译Android 源码出现OutOfMemoryError 错误解决
Exception in thread “main” java.lang.OutOfMemoryError: Java heap space 错误
在之前的编译过程中使用的是 2G swap
,遇到了内存溢出错误,而在编译 Android 7 系统时,是可以设定 JACK_SERVER_VM_ARGUMENTS
参数从而防止内存溢出的
如果编译的是Android 10 ,则将机器配置从 8G内存
,2G swap
,尝试设定为 8G 内存
,8G swap
。如果是编译 Android11 ,则要设定到 12G内存
,16G swap
然后设定内存限制的环境变量,在终端执行:
# 如果是编译 10
export _JAVA_OPTIONS="-Xmx4g"
# 如果是编译 11
export _JAVA_OPTIONS="-Xmx8g"
再使用 make
命令,而不是 make -j2
,这次没有使用多线程,成功编译。
但是耗时达到了 11 个小时(跑了一晚上)所以有大内存还是尽量使用大内存编译。
最关键的就是设定
_JAVA_OPTIONS
环境变量
理论上,编译任意Android系统,只要是编译过程中的OOM,都可以用这个环境变量限定内存使用
实际上还可以通过另一个环境变量设定java进程的内存限制:
export JAVA_TOOL_OPTIONS="-Xmx4g"
这两个环境变量,_JAVA_OPTIONS
会覆盖 JAVA_TOOL_OPTIONS
。所以一般设置 _JAVA_OPTIONS
就行
启动
在当前终端执行 emulator
启动 Android 模拟器
如果是在虚拟机中安装的 Ubuntu 进行系统编译的,启动这个模拟器可能会出现问题
VMware 需要开启CPU虚拟化,这样才可以在虚拟机中打开模拟器
如果是在新的终端启动模拟器,那么仍需要执行:
source build/envsetup.sh
lunch
也就是说在启动模拟器的终端里,必须执行 source build/envsetup.sh
和 lunch
之后才能执行 emulator
最终效果:
附:Ubuntu 扩展 swap 大小的方法
将 swap 设置为 16G :
sudo swapoff /swapfile
sudo dd if=/dev/zero of=/swapfile bs=1G count=16
sudo mkswap /swapfile
sudo swapon /swapfile