如何在Ubuntu上构建Android ROM

介绍

Android是当今世界上最流行的操作系统。数以百计的不同设备制造商选择将其安装在他们的设备上,因为它是免费的开源的,并且围绕它构建了大量的应用程序和服务生态系统。但是,许多厂商为了利益,很少会持续升级您的系统版本,迫使您购买新的设备以提升体验。同时,厂商也会使用制定系统,包含很多您用不到的软件,为了体验最新原生安卓系统,您可以尝试自行编译Android ROM。在Androidmodding社区中,此类固件通常称为ROM,即只读内存的缩写。

在本教程中,您将构建一个基于Android开源项目的Android Oreo ROM(简称:AOSP)。为了使本教程通用,我们将仅针对AOSP虚拟机,但您可以对实际设备应用相同的技术。

准备

为了项目能够正常开发,您需要:

  • 一台已经设置好可以使用sudo命令的非root账号的Ubuntu服务器,并且已开启防火墙。这台服务器我们建议的配置是16G内存,4核CPU,120G以上可用空间,没有服务器的同学可以在这里购买
  • 通过如何在Ubuntu系统上安装Git安装Git。

第一步 - 开始screen会话

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

开始一个新的screen会话。

screen

当您第一次运行屏幕时,您将获得许可协议。按Enter键接受许可证。

从现在开始,如果您的SSH连接失败,您长时间运行的命令将继续在后台运行。重新建立SSH连接后,您将能够通过运行screen -r恢复会话。接下来,让我们安装编译Android所需的组件。

第二步 - 安装依赖项

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源代码。

第三步 - 下载源代码

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

mkdir -p ~/aosp/oreo

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

cd ~/aosp/oreo

必须使用AOSP清单存储库初始化该目录,AOSP清单存储库是一个包含名为default.xml的XML文件的特殊Git存储库,它指定了共同构成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

上面的命令将会下载超过30GB的数据,因此在完成时要耐心等待。一旦完成,我们将设置一个缓存来加速编译。

第四步 - 准备编译器缓存

要加速构建,可以使用编译器缓存。顾名思义,编译器缓存可帮助您避免重新编译已编译的ROM部分。要启用编译器缓存,请设置名为USE_CCACHE的环境变量。

export USE_CCACHE=1

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

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

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

Set cache size limit to 15.0 Gbytes

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

第五步 - 配置JACK

Jack服务器负责构建ROM的大部分基于Java的部分,需要大量内存。为避免内存分配错误,您可以使用一个名为ANDROID_JACK_VM_ARGS的环境变量来指定允许Jack使用多少内存。通常,分配大约50%的服务器内存就足够了。此环境变量还指定其他编译设置。执行以下命令为Jack服务器分配8 GB的RAM,并保留Jack所需的默认编译选项:

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

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

第六步 - 开始构建

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

使用脚本来获取对辅助函数的访问权限。

source build/envsetup.sh
including 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命令并将设备的代号传递给它,后缀为构建类型,可以是enguserdebuguserenguserdebug构建类型最适合测试目的的ROM,建议将user构建类型用于生产用途。

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

lunch aosp_arm-eng

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

============================================
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

该命令返回CPUS的数量:

8

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

make -j8

即使有8个CPU,只要服务器上没有其他CPU进程处于活动状态,您就必须等待一个多小时才能完成构建。构建的持续时间与RAM的数量和CPU的数量成正比。如果您想要更快的构建,请考虑使用更多CPU的CVM,它最多支持32个CPU和48GB内存。

注意:您将在构建期间看到许多警告消息。 你可以忽略它们。

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

...
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)) ####

让我们验证一下构建正确的东西。

第七步 - 验证构建

构建过程的输出由多个系统映像组成,它们一起构成ROM。你会在out/target/product/generic/目录中找到它们。

ls -l out/target/product/generic/*.img
-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的提示。

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

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

注意:如果您尝试在模拟器启动之前打开shell,您将看到一条错误消息,通知您模拟器处于脱机状态。等一会儿再试一次。

故障排除

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

jack-admin kill-server

然后再次启动构建,允许更少的并行编译。例如,以下是如何将并行编译数减少到2:

make -j2

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

make clobber

或者,您可以使用腾讯云的云硬盘为CVM添加更多磁盘空间。

结论

在本教程中,您已成功为Android Oreo构建了基于AOSP的ROM。您今天学到的技术也适用于AOSP的所有分支,例如Lineage OSResurrection Remix OS。如果您有开发Android应用程序的经验,您可能有兴趣修改AOSP代码库的一小部分,以便为您的ROM提供个性化的服务。更多Linux教程请前往腾讯云+社区学习更多知识。


参考文献:《How to Build Android ROMs on Ubuntu 16.04》

原创声明,本文系作者授权云+社区发表,未经许可,不得转载。

如有侵权,请联系 yunjia_community@tencent.com 删除。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏散尽浮华

ELK实时日志分析平台环境部署--完整记录

在日常运维工作中,对于系统和业务日志的处理尤为重要。今天,在这里分享一下自己部署的ELK(+Redis)-开源实时日志分析平台的记录过程(仅依据本人的实际操作为...

5557
来自专栏搜云库

CentOs7.3 搭建 RabbitMQ 3.6 单机服务

CentOs7.3 搭建 RabbitMQ 3.6 单机服务 RabbitMQ简介 RabbitMQ是一个开源的AMQP实现,服务器端用Erlang语言编写,支...

31810
来自专栏pythonlove

Linux防火墙iptables(二)

上一篇文章我们说了一些iptables/netfilter的基础知识,本文我们来介绍一下iptables的规则编写。Iptables的规则可以概括的分为两个方面...

2892
来自专栏openshift持续集成

jenkins邮件插件中的内容参数设置

众所周知,Jenkins默认提供了一个邮件通知,能在构建失败、构建不稳定等状态后发送邮件。但是它本身有很多局限性,比如它的邮件通知无法提供详细的邮件内容、无法定...

8618
来自专栏FreeBuf

一款轻量级Web漏洞教学演示系统(DSVW)

Damn Small Vulnerable Web (DSVW) 是使用 Python 语言开发的 Web应用漏洞 的演练系统。其系统只有一个 python 的...

27510
来自专栏西安-晁州

小程序开发知识点总结

我承认,最近比较懒了,博客也很久没更新了,太对不住自己了,做了一段时间小程序开发,总结了一些知识点,直接上菜。

2301
来自专栏容器云生态

Docker1.12尝试

前言:在docker1.12中默认增加了swarm mode 编排功能,并且官方支持更多的插件来进行docker的网路和外接存储插件,不过目前测试swarm m...

45810
来自专栏张戈的专栏

如何确保NFS服务安全

上一篇博文《Redhat 设置 NFS 挂载的简单步骤》,其中摘录了一段 nfs 中 fuser 的使用,索性将其全部发出,以供参考。 ---- 对于 NFS ...

77512
来自专栏白驹过隙

Socket编程回顾,一个最简单服务器程序

2213
来自专栏雪胖纸的玩蛇日常

python3+django2 开发易语言网络验证(上)

3244

扫码关注云+社区

领取腾讯云代金券