如何在Ubuntu16.04上构建AndroidROM

来自菜鸟教程
跳转至:导航、​搜索

介绍

Android 是当今世界上最流行的操作系统。 数百家不同的原始设备制造商或 OEM 选择在他们的设备上安装它,因为它是免费的、开源的,并且围绕它构建了一个庞大的应用程序和服务生态系统。 不幸的是,许多 OEM 不会定期推送 Android 的无线 (OTA) 更新。 其他 OEM 仅在设备发布后的有限时间内提供更新。 此外,OEM 倾向于广泛定制 Android,以确保他们的设备具有独特的外观和感觉。 他们的定制包括替代启动器、主题系统用户界面和预安装的应用程序。

如果您想删除所有这些自定义设置,或者如果您想在您的设备上运行最新版本的纯 Android,您可以自己为其构建新固件。 在 Android 改装社区中,此类固件通常被称为 ROM,是 Read Only Memory 的缩写。

在本教程中,您将构建一个基于 Android 开源项目 或简称 AOSP 的 Android Oreo ROM。 为了保持本教程的设备独立性和通用性,我们将仅针对 AOSP 模拟器,但您可以将相同的技术应用于实际设备。

先决条件

为了能够跟进,您需要:

  • 一台 Ubuntu 16.04 x64 服务器,具有至少 16 GB 的 RAM、4 个 CPU 和 120 GB 的存储空间,按照 Ubuntu 16.04 初始服务器设置指南 进行设置,包括 sudo 非 root 用户和防火墙. 编译过程需要大量 RAM,更多的 CPU 会加快编译时间。 此外,您将要下载和构建的文件非常大。 DigitalOcean 有 High CPU Droplets 可能非常适合这个项目。
  • 按照 如何在 Ubuntu 16.04 上安装 Git 安装 Git。

第 1 步 — 开始屏幕会话

您将在本教程中执行的一些命令可能会运行数小时。 如果您的 PC 和服务器之间的 SSH 连接在命令运行时中断,它们将被突然终止。 为避免这种情况,请使用 screen 实用程序,它允许您在单个终端中运行多个控制台会话。 使用屏幕,您可以从正在运行的会话中分离并稍后重新附加到它。 如果您是 Screen 新手,请在 本教程中了解更多关于在 Ubuntu 上使用 Screen 的信息。

开始一个新的 screen 会话。

screen

当您第一次运行 screen 时,您将看到一份许可协议。 按 Enter 接受许可。

从此时起,如果您的 SSH 连接失败,您的长时间运行的命令将继续在后台运行。 重新建立 SSH 连接后,您将能够通过运行 screen -r 来恢复会话。

接下来,让我们安装编译Android所需的组件。

第 2 步 — 安装依赖项

AOSP 源代码分布在几个不同的 Git 存储库中。 为了让用户更容易下载所有这些存储库,AOSP 社区创建了一个名为 repo 的命令行工具。

我们将使用 wget 下载该工具的最新版本并将其存储在 ~/bin 目录中。 首先,创建~/bin目录:

mkdir -p ~/bin

然后下载repo脚本:

wget 'https://storage.googleapis.com/git-repo-downloads/repo' -P ~/bin

注意:如果您担心在您的机器上运行从其他站点下载的脚本的安全性,请检查脚本的内容:

less ~/bin/repo

一旦您对脚本的内容感到满意,请继续学习本教程。


使用 chmod 授予当前用户运行 repo 的权限。

chmod +x ~/bin/repo

repo 工具在内部使用 Git,并要求您创建一个 Git 配置,指定您的用户名和电子邮件地址。 执行这些命令来做到这一点:

git config --global user.name "your name"
git config --global user.email "your_email@your_domain.com"

Android 的源代码主要由 Java、C++ 和 XML 文件组成。 要编译源代码,您需要安装 OpenJDK 8、GNU C 和 C++ 编译器、XML 解析库、ImageMagick 和其他几个相关包。 幸运的是,您可以使用 apt 安装所有这些。 在您这样做之前,请确保您更新了服务器的软件包列表。

sudo apt-get update

列表更新后,安装依赖项:

sudo apt-get install openjdk-8-jdk android-tools-adb bc bison build-essential curl flex g++-multilib gcc-multilib gnupg gperf imagemagick lib32ncurses5-dev lib32readline-dev lib32z1-dev libesd0-dev liblz4-tool libncurses5-dev libsdl1.2-dev libssl-dev libwxgtk3.0-dev libxml2 libxml2-utils lzop pngcrush rsync schedtool squashfs-tools xsltproc yasm zip zlib1g-dev

依赖包下载完成后,我们可以使用 repo 脚本来获取 Android 源代码。

第 3 步 — 下载源代码

我们将使用 repo 脚本来执行一些任务来准备我们的工作区。 创建一个新目录来存储您要下载的 Android 源代码:

mkdir -p ~/aosp/oreo

在本教程的其余部分中,您将在此目录中工作,所以现在切换到它:

cd ~/aosp/oreo

该目录必须使用 AOSP 清单存储库 进行初始化,这是一个特殊的 Git 存储库,其中包含一个名为 default.xml 的 XML 文件,它指定了共同构成 AOSP 代码库的所有其他 Git 存储库的路径。

使用整个 AOSP 代码树会变得很麻烦。 因此,您必须另外指定您感兴趣的特定修订或分支的名称。 在本教程中,因为我们正在构建 Oreo ROM,我们将使用 android-8.0.0_r33 分支,其构建 ID 为 OPD1.170816.025。 您可以从 AOSP 的官方 代号、标签和内部版本号 页面获取所有可用构建 ID 和分支名称的列表。

此外,您将不需要本教程的代码树的整个提交历史。 您可以通过将历史截断到 1 的深度来节省时间和存储空间。

因此,使用 repo init 命令初始化目录并指定以下选项:

repo init -u https://android.googlesource.com/platform/manifest -b android-8.0.0_r33 --depth=1

当提示启用彩色显示时,按 Y,然后按 Enter

最后,通过运行 repo sync 命令从各个存储库下载实际的 AOSP 文件:

repo sync

上述命令会下载超过 30 GB 的数据,因此请耐心等待完成。 完成后,我们将设置缓存以加快编译速度。

第 4 步 — 准备编译器缓存

为了加快构建速度,您可以使用编译器缓存。 顾名思义,编译器缓存可帮助您避免重新编译已编译的 ROM 部分。

要启用编译器缓存,请设置一个名为 USE_CCACHE 的环境变量。

export USE_CCACHE=1

除非您有大量可用磁盘空间,否则您不希望缓存变得太大,因此您可以限制其大小。 如果您正在为单个设备构建 ROM,则可以将其限制为 15 GB。 为此,请使用 ccache 命令。

prebuilts/misc/linux-x86/ccache/ccache -M 15G

您将看到确认您已进行此更改的输出:

OutputSet cache size limit to 15.0 Gbytes

在编译之前,我们还需要进行一项优化。 接下来让我们这样做。

第 5 步 — 配置 Jack

Jack 服务器负责构建 ROM 的大部分基于 Java 的部分,它需要大量内存。 为避免内存分配错误,您可以使用名为 ANDROID_JACK_VM_ARGS 的环境变量来指定 Jack 可以使用多少内存。 通常,分配大约 50% of 的服务器 RAM 就足够了。 此环境变量还指定其他编译设置。

执行以下命令为 Jack 服务器分配 8 GB RAM 并保留 Jack 需要的默认编译选项:

export ANDROID_JACK_VM_ARGS="-Xmx8g -Dfile.encoding=UTF-8 -XX:+TieredCompilation"

现在您已准备好构建您的 Android ROM。

第 6 步 — 开始构建

AOSP 代码树包含一个名为 envsetup.sh 的脚本,它有几个与构建相关的帮助函数。 虽然许多辅助函数,例如 mmmmammm,充当 make 命令的快捷方式,但其他的例如 lunch 设置重要的环境变量,其中包括决定 ROM 的 CPU 架构和构建类型。

获取脚本以获得对辅助函数的访问权限。

source build/envsetup.sh
Outputincluding device/asus/fugu/vendorsetup.sh
including device/generic/car/car-arm64/vendorsetup.sh
including device/generic/car/car-armv7-a-neon/vendorsetup.sh
including device/generic/car/car-x86_64/vendorsetup.sh
including device/generic/car/car-x86/vendorsetup.sh
including device/generic/mini-emulator-arm64/vendorsetup.sh
including device/generic/mini-emulator-armv7-a-neon/vendorsetup.sh
including device/generic/mini-emulator-mips64/vendorsetup.sh
including device/generic/mini-emulator-mips/vendorsetup.sh
including device/generic/mini-emulator-x86_64/vendorsetup.sh
including device/generic/mini-emulator-x86/vendorsetup.sh
including device/google/dragon/vendorsetup.sh
including device/google/marlin/vendorsetup.sh
including device/google/muskie/vendorsetup.sh
including device/google/taimen/vendorsetup.sh
including device/huawei/angler/vendorsetup.sh
including device/lge/bullhead/vendorsetup.sh
including device/linaro/hikey/vendorsetup.sh
including sdk/bash_completion/adb.bash

接下来,运行 lunch 并将设备的代号传递给它,并以构建类型为后缀,可以是 enguserdebuguser . 虽然 enguserdebug 构建类型会生成最适合测试目的的 ROM,但建议将 user 构建类型用于生产用途。

要构建可以在 AOSP ARM 仿真器上运行的测试 ROM,请将 aosp_arm-eng 传递给 lunch 命令:

lunch aosp_arm-eng

您将看到此输出,其中显示了环境设置:

Output============================================
PLATFORM_VERSION_CODENAME=REL
PLATFORM_VERSION=8.0.0
TARGET_PRODUCT=aosp_arm
TARGET_BUILD_VARIANT=eng
TARGET_BUILD_TYPE=release
TARGET_PLATFORM_VERSION=OPD1
TARGET_BUILD_APPS=
TARGET_ARCH=arm
TARGET_ARCH_VARIANT=armv7-a
TARGET_CPU_VARIANT=generic
TARGET_2ND_ARCH=
TARGET_2ND_ARCH_VARIANT=
TARGET_2ND_CPU_VARIANT=
HOST_ARCH=x86_64
HOST_2ND_ARCH=x86
HOST_OS=linux
HOST_OS_EXTRA=Linux-4.4.0-104-generic-x86_64-with-Ubuntu-16.04-xenial
HOST_CROSS_OS=windows
HOST_CROSS_ARCH=x86
HOST_CROSS_2ND_ARCH=x86_64
HOST_BUILD_TYPE=release
BUILD_ID=OPD1.170816.025
OUT_DIR=out
AUX_OS_VARIANT_LIST=
============================================

最后,运行 make 开始构建。 make 支持并行作业,因此您可以通过使用 -j 选项将并行作业的数量设置为服务器中可用的 CPU 数量来大大加快构建速度。

使用 nproc 命令查看你有多少 CPU:

nproc

该命令返回 CPU 的数量:

Output8

然后,您可以将此数字与 make 一起使用来指定并行执行:

make -j8

即使有 8 个 CPU,您也必须等待一个多小时才能完成构建,前提是您的服务器上没有其他活动的 CPU 密集型进程。 构建的持续时间与您拥有的 RAM 数量和 CPU 数量成正比。 如果您想要更快的构建,请考虑使用专用的 High CPU Droplets,它支持多达 32 个 CPU 和 48 GB 内存。

注意: 在构建过程中你会看到很多警告信息。 您可以放心地忽略它们。


ROM 准备好后,您应该会看到一条消息,说明构建已成功完成。 您还可以看到构建的确切持续时间。

Output...
Creating filesystem with parameters:
    Size: 2147483648
    Block size: 4096
    Blocks per group: 32768
    Inodes per group: 8192
    Inode size: 256
    Journal blocks: 8192
    Label: system
    Blocks: 524288
    Block groups: 16
    Reserved block group size: 127
Created filesystem with 2266/131072 inodes and 178244/524288 blocks
[100% 63193/63193] Install system fs i... out/target/product/generic/system.img
out/target/product/generic/system.img+ maxsize=2192446080 blocksize=2112 total=2147483648 reserve=22146432

#### make completed successfully (01:05:44 (hh:mm:ss)) ####

让我们验证事物是否正确构建。

第 7 步 — 验证构建

构建过程的输出由多个文件系统映像组成,它们共同构成 ROM。 您可以在 out/target/product/generic/ 目录中找到它们。

ls -l out/target/product/generic/*.img
Output-rw-r--r-- 1 sammy sammy   69206016 Jan  5 18:51 out/target/product/generic/cache.img
-rw-rw-r-- 1 sammy sammy    1699731 Jan  5 19:09 out/target/product/generic/ramdisk.img
-rw-r--r-- 1 sammy sammy 2147483648 Jan  5 19:10 out/target/product/generic/system.img
-rw-r--r-- 1 sammy sammy  576716800 Jan  5 19:09 out/target/product/generic/userdata.img

要测试 ROM,您可以尝试通过运行 emulator 命令来启动模拟器。 如果您在非 GUI 环境中,请确保将 -no-window-noaudio 标志传递给它。

emulator -no-window -noaudio > /dev/null 2>&1 &

要检查模拟器是否能够成功启动,请稍等片刻,然后使用 Android 调试桥接工具 adb 在模拟器上打开一个 shell。

adb shell

如果 ROM 没有问题,您将看到来自模拟器上运行的 shell 的提示。

Output* daemon not running; starting now at tcp:5037
* daemon started successfully
generic:/ #

通过键入 exit 并按 ENTER 或按 CTRL+D 退出此 shell。

注意: 如果您在模拟器启动前尝试打开外壳,您将看到一条错误消息,通知您模拟器已离线。 稍等片刻,然后重试。


故障排除

如果您的构建失败,最可能的原因是内存不足。 要修复它,首先通过运行以下命令终止 Jack 服务器:

jack-admin kill-server

然后再次开始构建,但允许的并行作业更少。 例如,以下是如何将并行作业的数量减少到 2 个:

make -j2

如果您的构建由于磁盘空间不足而失败,您可能会尝试多次构建而不清理先前构建的结果。 要丢弃以前构建的结果,可以运行以下命令:

make clobber

或者,您可以使用 DigitalOcean 的 块存储 为您的 Droplet 添加更多磁盘空间。

结论

在本教程中,您成功地为 Android Oreo 构建了一个基于 AOSP 的 ROM。 你今天学到的技术也适用于 AOSP 的所有分支,例如 Lineage OSResurrection Remix OS。 如果您有开发 Android 应用程序的经验,您可能有兴趣修改 AOSP 代码库的一小部分以使您的 ROM 具有个人风格。

要了解有关构建 AOSP 源代码的更多信息,请浏览 Google Groups 上的 Android 构建论坛