编译 Android

请参阅 Android 开源项目 (AOSP) 中的 Android Make 编译系统说明,了解相关说明以及 Android.mk 编写人员须知的编译系统更改

Soong 编译系统是在 Android 8.0 (Oreo) 中引入的。如需查看示例的 Soong 配置(Blueprint 或 .bp)文件,请参阅简单的编译配置;您还可以查看 Soong 参考文件以了解完整详情。

设置环境

使用 envsetup.sh 脚本初始化环境。请注意,将 source 替换成 .(一个点)可以省去一些字符,这种简写形式在文档中更为常用。

source build/envsetup.sh

. build/envsetup.sh

您将需要在每次运行 repo sync 后重新发出此命令,以获取对该脚本所做的任何更改。

envsetup.sh 脚本导入了一些命令,可让您使用 Android 源代码,其中包括本练习中使用的命令。以下是一些重要的命令示例:

  • lunch - lunch product_name-build_variant 会选择“product_name”作为要编译的产品,并选择“build_variant”作为要编译的变体,然后将这些选择存储在可被后续对 m 和其他类似命令的调用读取的环境中。
  • m - 从树的顶部运行编译。这很有用,因为您可以在子目录中运行 make。如果您设置了 TOP 环境变量,它便会使用此变量。如果您未设置此变量,它便会从当前目录中查找相应的树,以尝试找到树的顶层。您可以通过运行不包含参数的 m 来编译整个源代码树,也可以通过指定相应名称来编译特定目标。
  • mma - 编译当前目录中的所有模块及其依赖项。
  • mmma - 编译提供的目录中的所有模块及其依赖项。
  • croot - cd 到树顶部。

要查看可用命令的完整列表,请运行以下命令:

hmm

选择目标

使用 lunch 选择要编译的目标。确切的配置可作为参数进行传递。例如,以下命令表示针对模拟器进行完整编译,并且启用所有调试功能.

lunch aosp_arm-eng

如果在没有参数的情况下运行,则 lunch 会提示您从菜单中选择目标。要了解所有现有设备的编译配置,请参阅选择设备编译系统一文。

所有编译目标都采用 BUILD-BUILDTYPE 形式,其中 BUILD 是表示特定功能组合的代号。BUILDTYPE 是以下类型之一。

编译类型 使用情况
user 权限受限;适用于生产环境
userdebug 与“user”类似,但具有 root 权限和调试功能;是进行调试时的首选编译类型
eng 具有额外调试工具的开发配置

userdebug 版本的运行方式应该与 user 版本一样,且能够启用通常不符合平台安全模型的额外调试功能。这就使得 userdebug 版本具有更强大的诊断功能,因此是进行 user 测试的最佳选择。使用 userdebug 编译系统进行开发时,请遵循 userdebug 指南

eng 编译系统会优先考虑在平台上工作的工程师的工程生产率。eng 编译系统会关闭用于提供良好用户体验的各种优化。除此之外,eng 编译系统的运行方式类似于 user 和 userdebug 编译系统,以便设备开发者能够看到代码在这些环境下的运行方式。

要详细了解如何针对实际硬件进行编译以及如何在实际硬件上运行编译系统,请参阅运行编译系统

编译代码

本部分是一个简短摘要,用于确保设置已完成。

请使用 m 进行所有编译。m 可以使用 -jN 参数处理并行任务。如果您未提供 -j 参数,编译系统便会自动选择其认为对您的系统最佳的并行任务计数。

m

如上所述,您可以通过在 m 命令行中列出相应名称来编译特定模块,而不是编译完整的设备映像。此外,m 还针对各种特殊目的提供了一些伪目标。以下是一些示例:

  • droid - m droid 是正常编译。此目标在此处,因为默认目标需要名称。
  • all - m all 可以编译 m droid 能够编译的所有元素,以及没有 droid 标记的所有元素。编译服务器会运行此命令,以确保包含在树中且包含 Android.mk 文件的所有元素都会进行编译。
  • clean - m clean 可以删除此配置的所有输出文件和中间文件。这与 rm -rf out/ 相同。

运行 m help 即可查看 m 提供的其他伪目标。

开始运行!

您可以在模拟器上运行编译系统,也可以将其刷到设备上。请注意,您已经使用 lunch 选择了编译目标,并且编译系统不可能在与编译目标不同的目标上运行。

使用 fastboot 刷机

要刷写设备,请使用 fastboot;在成功编译后,它应该会包含在您的路径中。如需相关说明,请参阅刷写设备

模拟 Android 设备

编译流程会自动将模拟器添加到您的路径中。要运行模拟器,请输入以下命令:

emulator

排查常见编译错误

Java 版本不正确

如果您试图编译与 Java 版本不一致的 Android 版本,则 make 会终止并显示如下消息:

************************************************************
You are attempting to build with the incorrect version
of java.

Your version is: WRONG_VERSION.
The correct version is: RIGHT_VERSION.

Please follow the machine setup instructions at
    https://source.android.com/source/initializing.html
************************************************************

以下是可能的原因和解决方案:

  • 无法按照 JDK 要求中指定的方式安装正确的 JDK。请确保您已按照设置环境选择目标中的步骤操作。
  • 之前安装的另一个 JDK 出现在您的路径中。将正确的 JDK 附加到路径开头,或者移除有问题的 JDK。

Python 版本 3

Repo 是基于 Python 2.x 中的特定功能构建的,与 Python 3 不兼容。要使用 Repo,请安装 Python 2.x:

apt-get install python

不区分大小写的文件系统

在 macOS 中的 HFS 文件系统上进行编译时,可能会遇到如下错误:

************************************************************
You are building on a case-insensitive filesystem.
Please move your source tree to a case-sensitive filesystem.
************************************************************

请按照创建区分大小写的磁盘映像中的说明操作。

没有 USB 权限

默认情况下,在大多数 Linux 系统中,无特权的用户无法使用 USB 端口。如果您看到权限遭拒错误,请按照配置 USB 使用权限中的说明操作。

如果上述规则设置完成后,adb 已在运行且无法连接到设备,您可以使用 adb kill-server 将其终止。此命令将使 adb 重启并采用新配置。