介绍
[Android] (https://www.android.com/)是当今世界最受欢迎的操作系统. 数百个不同的原始设备制造商,即OEMs,选择在他们的设备上安装,因为它是免费的,开源的,并拥有围绕它而建的应用和服务的巨大生态系统. 不幸的是,许多OEM并不定期为Android提供超空(OTA)更新. 而其他的OEMs只在设备发射后提供有限的更新时间. 此外,OEMs还倾向于对Android进行广泛的定制,以确保它们的设备能运动出独特的外观和感受. 他们的定制包括替代发射器,主题系统用户界面,以及预先安装的应用软件.
如果你想删除所有这些定制,或者如果你想在你的设备上运行纯 Android 的最新版本,你可以为它自己构建新的固件。
在本教程中,您将构建基于 Android 开源项目的 Android Oreo ROM,或简而言之为 AOSP。
前提条件
为了能够跟随,你将需要:
- 1个 Ubuntu 16.04 x64 服务器,至少有 16 GB RAM, 4 CPU, 120 GB 的存储空间,通过跟随Ubuntu 16.04 初始服务器设置指南,包括一个sudo 非root用户和一个防火墙. 编译过程需要大量的RAM,而更多的CPU会加快编译时间. 此外,您将下载和建设的文件相当庞大. DigitalOcean有高CPU Droplets,这也许非常适合这个项目.
- Git通过下列方式安装:如何在Ubuntu 16.04上安装Git。 .
步骤1 - 启动屏幕会话
在这个教程中您将执行的一些命令有可能运行数小时. 如果您的PC和服务器之间的SSH连接在命令运行时被中断,它们就会被突然终止. 为避免这种情况,使用 " 屏幕 " 工具,使您可以在一个终端上运行多个控制台会话。 通过屏幕,您可以从运行的会话中解析出来,并在稍后重新接上. 如果您是新来屏幕的, 请在 [这个在 Ubuntu 上使用屏幕的教程] (https://andsky.com/tech/tutorials/how-to-install-and-use-screen-on-an-ubuntu-cloud-server) 中学习更多 .
开始一个新的屏幕
会话。
1screen
当您第一次运行屏幕时,您将收到许可协议. 按 Enter 以接受许可证。
从此开始,如果您的 SSH 连接失败,您的长期运行命令将继续在背景中运行.一旦您重新建立 SSH 连接,您将能够通过运行屏幕 -r
来恢复会话。
接下来,让我们安装我们需要编译 Android 的组件。
第2步:安装依赖性
AOSP 源代码分布在多个不同的 Git 存储库中,为了让用户更容易地下载所有这些存储库,AOSP 社区创建了一个命令行工具,名为 repo
。
我们将使用wget
下载工具的最新版本,并将其存储在~/bin
目录中,首先创建~/bin
目录:
1mkdir -p ~/bin
然后下载repo
脚本:
1wget 'https://storage.googleapis.com/git-repo-downloads/repo' -P ~/bin
注:如果您担心您从其他网站下载的脚本在您的机器上运行的安全性,请检查脚本的内容:
1less ~/bin/repo
一旦您对脚本的内容感到满意,请继续使用本教程。
使用chmod
授予当前用户运行repo
的权限。
1chmod +x ~/bin/repo
repo
工具使用Git内部,并要求您创建一个Git配置,指定您的用户名和电子邮件地址。
1git config --global user.name "your name"
2git config --global user.email "your_email@your_domain.com"
Android的源代码主要由Java,C++和XML文件组成,要编译源代码,您需要安装OpenJDK 8,GNU C和C++编译器,XML分析库,ImageMagick和其他几个相关包。
1sudo apt-get update
一旦列表更新,安装依赖:
1sudo 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源:
1mkdir -p ~/aosp/oreo
您将在本教程的剩余时间内在这个目录中工作,所以现在切换到它:
1cd ~/aosp/oreo
该目录必须与AOSP( manifesto repository)(LINK0)初始化,这是一个包含一个名为default.xml的XML文件的特殊Git repository,它指定了组成AOSP代码库的所有其他Git repository的路径。
在本教程中,因为我们正在构建Oreo ROM,我们将使用Android-8.0.0_r33
分支,其构建ID是OPD1.170816.025
。
此外,您将不需要这个教程的代码树的整个承诺历史记录,您可以节省时间和存储空间,将历史记录缩小到1
的深度。
因此,使用repo init
命令来初始化目录并指定这些选项:
1repo init -u https://android.googlesource.com/platform/manifest -b android-8.0.0_r33 --depth=1
当被提示启用彩色显示时,按 Y ,然后按 ** Enter** 。
最后,从各种存储库下载实际的 AOSP 文件,运行repo sync
命令:
1repo sync
上面的命令下载超过 30 GB 的数据,所以在完成时要耐心。
步骤4 – 准备一个编译器缓存
要加快构建速度,您可以使用编译器缓存,正如其名称所示,编译器缓存可以帮助您避免重新编译已编译的ROM部分。
要启用编译器缓存,设置一个名为USE_CCACHE
的环境变量。
1export USE_CCACHE=1
除非您有大量的自由磁盘空间,否则您不希望缓存太大,因此您可以限制其大小;如果您正在为单个设备构建您的ROM,您可以将其限制到15 GB。
1prebuilts/misc/linux-x86/ccache/ccache -M 15G
您将看到确认您已执行此更改的输出:
1[secondary_label Output]
2Set cache size limit to 15.0 Gbytes
在我们可以编译之前,我们还需要进行一项优化。
第5步:设置Jack
Jack 服务器,负责构建 ROM 基于 Java 的大部分部分,需要大量的内存。为了避免内存分配错误,您可以使用名为ANDROID_JACK_VM_ARGS
的环境变量来指定允许使用内存 Jack 的数量。
执行以下命令,将 8 GB 的 RAM 分配给 Jack 服务器,并保留 Jack 需要的默认编译选项:
1export ANDROID_JACK_VM_ARGS="-Xmx8g -Dfile.encoding=UTF-8 -XX:+TieredCompilation"
现在你已经准备好构建你的Android ROM了。
步骤6 - 开始构建
AOSP代码树包含一个名为envsetup.sh
的脚本,该脚本具有几个与构建相关的辅助函数,而许多辅助函数,如mm
,mma
和mmm
,作为做
命令的捷径,其他人,如午餐
设置了重要的环境变量,这些变量,包括决定ROM的CPU架构,以及构建的类型。
源脚本,以获取访问辅助函数。
1source build/envsetup.sh
1[secondary_label Output]
2including device/asus/fugu/vendorsetup.sh
3including device/generic/car/car-arm64/vendorsetup.sh
4including device/generic/car/car-armv7-a-neon/vendorsetup.sh
5including device/generic/car/car-x86_64/vendorsetup.sh
6including device/generic/car/car-x86/vendorsetup.sh
7including device/generic/mini-emulator-arm64/vendorsetup.sh
8including device/generic/mini-emulator-armv7-a-neon/vendorsetup.sh
9including device/generic/mini-emulator-mips64/vendorsetup.sh
10including device/generic/mini-emulator-mips/vendorsetup.sh
11including device/generic/mini-emulator-x86_64/vendorsetup.sh
12including device/generic/mini-emulator-x86/vendorsetup.sh
13including device/google/dragon/vendorsetup.sh
14including device/google/marlin/vendorsetup.sh
15including device/google/muskie/vendorsetup.sh
16including device/google/taimen/vendorsetup.sh
17including device/huawei/angler/vendorsetup.sh
18including device/lge/bullhead/vendorsetup.sh
19including device/linaro/hikey/vendorsetup.sh
20including sdk/bash_completion/adb.bash
接下来,运行午餐
并将设备的代码名称传递给它,附带一个构建类型,可以是eng
,userdebug
或用户
。
要构建可在 AOSP ARM 模拟器上运行的试用 ROM,请将aosp_arm-eng
传输到午餐
命令:
1lunch aosp_arm-eng
您将看到此输出,显示环境设置:
1[secondary_label Output]
2============================================
3PLATFORM_VERSION_CODENAME=REL
4PLATFORM_VERSION=8.0.0
5TARGET_PRODUCT=aosp_arm
6TARGET_BUILD_VARIANT=eng
7TARGET_BUILD_TYPE=release
8TARGET_PLATFORM_VERSION=OPD1
9TARGET_BUILD_APPS=
10TARGET_ARCH=arm
11TARGET_ARCH_VARIANT=armv7-a
12TARGET_CPU_VARIANT=generic
13TARGET_2ND_ARCH=
14TARGET_2ND_ARCH_VARIANT=
15TARGET_2ND_CPU_VARIANT=
16HOST_ARCH=x86_64
17HOST_2ND_ARCH=x86
18HOST_OS=linux
19HOST_OS_EXTRA=Linux-4.4.0-104-generic-x86_64-with-Ubuntu-16.04-xenial
20HOST_CROSS_OS=windows
21HOST_CROSS_ARCH=x86
22HOST_CROSS_2ND_ARCH=x86_64
23HOST_BUILD_TYPE=release
24BUILD_ID=OPD1.170816.025
25OUT_DIR=out
26AUX_OS_VARIANT_LIST=
27============================================
最后,运行做
来启动构建。做
支持并行任务,因此您可以通过使用-j
选项将并行任务的数量设置为服务器中可用的CPU数量来大大加速构建。
使用nproc
命令查看您有多少CPU:
1nproc
该命令返回 CPUS 号码:
1[secondary_label Output]
28
然后,您可以使用这个数字与做
来指定并行执行:
1make -j8
即使有 8 个 CPU,您也需要等待超过一个小时才能完成构建,只要您的服务器上没有其他 CPU 密集的流程。构建的持续时间与您所拥有的 RAM 和 CPU 数量直接相比例。
注意:你会看到许多在构建过程中生成的警告消息,你可以安全地忽略它们。
一旦 ROM 准备好了,你应该看到一个消息,说明构建成功完成,你也可以看到构建的确切持续时间。
1[secondary_label Output]
2...
3Creating filesystem with parameters:
4 Size: 2147483648
5 Block size: 4096
6 Blocks per group: 32768
7 Inodes per group: 8192
8 Inode size: 256
9 Journal blocks: 8192
10 Label: system
11 Blocks: 524288
12 Block groups: 16
13 Reserved block group size: 127
14Created filesystem with 2266/131072 inodes and 178244/524288 blocks
15[100% 63193/63193] Install system fs i... out/target/product/generic/system.img
16out/target/product/generic/system.img+ maxsize=2192446080 blocksize=2112 total=2147483648 reserve=22146432
17
18#### make completed successfully (01:05:44 (hh:mm:ss)) ####
让我们看看这些东西是正确建造的。
步骤7 - 验证构建
构建过程的输出由多个文件系统图像组成,这些图像一起构成ROM,您可以在out/target/product/generic/
目录中找到它们。
1ls -l out/target/product/generic/*.img
1[secondary_label Output]
2-rw-r--r-- 1 sammy sammy 69206016 Jan 5 18:51 out/target/product/generic/cache.img
3-rw-rw-r-- 1 sammy sammy 1699731 Jan 5 19:09 out/target/product/generic/ramdisk.img
4-rw-r--r-- 1 sammy sammy 2147483648 Jan 5 19:10 out/target/product/generic/system.img
5-rw-r--r-- 1 sammy sammy 576716800 Jan 5 19:09 out/target/product/generic/userdata.img
要测试ROM,您可以尝试通过运行模拟器
命令启动一个模拟器,如果您处于非GUI环境中,请确保您将无窗口
和无声音
旗帜传递给它。
1emulator -no-window -noaudio > /dev/null 2>&1 &
要检查模拟器是否成功启动,请等待一分钟,然后使用 Android 调试桥工具adb
打开模拟器上的壳。
1adb shell
如果ROM没有问题,你会看到一个从模拟器上运行的壳的提示。
1[secondary_label Output]
2* daemon not running; starting now at tcp:5037
3* daemon started successfully
4generic:/ #
输出此壳,键入输出
并按ENTER
,或按CTRL+D
。
注意: 如果您尝试在模拟器启动之前打开壳,则会看到错误消息,通知您模拟器已离线。
解决问题
如果你的构建失败了,最有可能的原因是内存不足. 要修复它,先用以下命令杀死Jack服务器:
1jack-admin kill-server
然后重新开始构建,但允许更少的并行工作. 例如,以下是如何将并行工作数量减少到 2:
1make -j2
如果您的构建由于磁盘空间不足而失败,您可能正在尝试多次构建而不清除以前的构建的结果。
1make clobber
或者,您可以通过使用 DigitalOcean 的 Block Storage来添加更多的磁盘空间。
结论
在本教程中,您成功地为 Android Oreo 构建了基于 AOSP 的 ROM. 今天您学到的技术也适用于 AOSP 的所有叉子,例如 Lineage OS和 Resurrection Remix OS。
要了解有关构建 AOSP 源代码的更多信息,请浏览 Google 组的 Android 构建论坛。