编译 Android 系统镜像(Android 10 和 Android 11 )

编译 Android 系统镜像(Android 10 和 Android 11 )

前段时间下载了 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.shlunch 之后才能执行 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

Copyright: 采用 知识共享署名4.0 国际许可协议进行许可

Links: https://zwc365.com/2020/09/13/ubuntu18-build-android10-11