添加新设备

您可以参考本页中的信息为自己的设备和产品创建 Makefile。

每个新的 Android 模块都必须具有配置文件,以使用模块元数据、编译时依赖项和打包指令来指引构建系统。Android 使用 Soong 构建系统。如需详细了解 Android 构建系统,请参阅构建 Android

了解构建层

构建层次结构包括与设备的物理结构对应的抽象层。下表中介绍了这些层。每一层都与上一层存在一对多的关系。例如,一个架构可以有多个主板,一个主板可以有多个产品。您可以将指定层中的某个元素定义为同一层中某个元素的特化元素,这样可以免去复制操作并简化维护工作。

示例 说明
产品 myProduct、myProduct_eu、myProduct_eu_fr、j2 和 sdk 产品层用于定义所开发产品的功能规范,例如要构建的模块、支持的语言区域,以及针对各语言区域的配置。也就是说,这是总体产品的名称。产品特定变量在产品定义 Makefile 中进行定义。一个产品可以沿用其他产品的定义,这有助于简化维护工作。一种常用的方法是:先创建一个基础产品,其中包含会应用到所有产品的功能,然后再基于这个基础产品创建产品变体。例如,如果有两个产品只是使用的无线技术不同(分别使用 CDMA 和 GSM),那么它们可以沿用未定义无线技术的同一个基础产品的定义。
主板/设备 marlin、blueline 和 coral 主板/设备层表示设备上由可塑材料组成的物理层(即,设备的工业设计)。此层还表示产品的基本架构图。这些架构图包括主板上的外围设备及其配置。所使用的名称只不过是代表不同主板/设备配置的代码。
架构 arm、x86、arm64 和 x86_64 架构层用于描述主板上运行的处理器配置和应用二进制接口 (ABI)。

使用构建变体

在针对特定产品进行构建时,如果能在最终发布版本的基础上有细微的变化,会非常有用。在模块定义中,模块可以通过 LOCAL_MODULE_TAGS 指定标记,这些标记可以是以下一个或多个值:optional(默认值)、debugeng

如果某个模块没有通过 LOCAL_MODULE_TAGS 指定标记,则其标记默认设置为 optional。仅当 PRODUCT_PACKAGES 的产品配置需要可选模块时,系统才会安装可选模块。

下面是当前定义的构建变体。

变体 说明
eng 这是默认类型。
  • 安装带有 engdebug 标记的模块。
  • 除了带有标记的模块之外,还会根据产品定义文件安装相应模块。
  • ro.secure=0
  • ro.debuggable=1
  • ro.kernel.android.checkjni=1
  • adb 默认处于启用状态。
user 要作为最终发布版本的变体。
  • 安装带有 user 标记的模块。
  • 除了带有标记的模块之外,还会根据产品定义文件安装相应模块。
  • ro.secure=1
  • ro.debuggable=0
  • adb 默认处于停用状态。
userdebug user 相同,但以下几点除外:
  • 还会安装带有 debug 标记的模块。
  • ro.debuggable=1
  • adb 默认处于启用状态。

userdebug 的准则

在测试中运行 userdebug 版本有助于设备开发者了解开发中版本的性能和功耗。为了让 user 版本和 userdebug 版本保持一致,并在用于调试的版本中获得可靠的指标,设备开发者应遵循以下准则:

  • userdebug 定义为已启用 root 权限的 user 版本,但以下情况除外:
    • 仅由用户视需要运行且仅用于 userdebug 版本的应用
    • 仅在空闲维护(连接充电器/充满电)期间执行的操作,例如,使用 dex2oatd 而不是 dex2oat 来进行后台编译
  • 不要添加根据构建类型默认启用/停用的功能。建议开发者不要使用任何影响电池续航时间的日志记录形式(例如调试日志记录或堆转储)。
  • 在 userdebug 版本中默认启用的任何调试功能都应明确定义,并告知处理相关项目的所有开发者。您应该只在限定的时间内启用调试功能,直到您尝试调试的问题得到解决。

利用资源叠加层自定义版本

Android 构建系统会在构建时使用资源叠加层来自定义产品。资源叠加层用于指定在默认文件之上应用的资源文件。要使用资源叠加层,请修改项目构建文件,将 PRODUCT_PACKAGE_OVERLAYS 设为相对于顶级目录的路径。当构建系统搜索资源时,该路径会变为影子根目录,系统除了在当前根目录中进行搜索外,还会一并在该路径中进行搜索。

最常自定义的设置包含在 frameworks/base/core/res/res/values/config.xml 文件中。

要在此文件上设置资源叠加层,请使用以下某个命令将叠加层目录添加到项目构建文件:

    PRODUCT_PACKAGE_OVERLAYS := device/device-implementer/device-name/overlay
    

    PRODUCT_PACKAGE_OVERLAYS := vendor/vendor-name/overlay
    

然后,将一个叠加层文件添加到该目录下,例如:

    vendor/foobar/overlay/frameworks/base/core/res/res/config.xml
    

在叠加层 config.xml 文件中找到的所有字符串或字符串数组都会替换在原始文件中找到的对应字符串或字符串数组。

构建产品

您可以通过多种不同的方式来组织设备的源文件。下面简要说明了 Pixel 实现的一种组织方式。

为 Pixel 实现了名为 marlin 的主设备配置。根据此设备配置,为产品创建了产品定义 Makefile,用于声明关于设备的产品特定信息,例如名称和型号。您可以查看 device/google/marlin 目录,了解所有相关配置的具体设置方式。

编写产品 Makefile

以下步骤介绍了如何采用与设置 Pixel 产品线类似的方式设置产品 Makefile:

  1. 为您的产品创建一个 device/<company-name>/<device-name> 目录。例如,device/google/marlin。此目录将包含您设备的源代码以及构建这些代码所需的 Makefile。
  2. 创建一个 device.mk Makefile,用来声明设备所需的文件和模块。有关示例,请查看 device/google/marlin/device-marlin.mk
  3. 创建一个产品定义 Makefile,以便基于设备创建具体产品。以下示例 Makefile 来自于 device/google/marlin/aosp_marlin.mk。请注意,该产品会通过 Makefile 沿用 device/google/marlin/device-marlin.mkvendor/google/marlin/device-vendor-marlin.mk 文件中的设置,同时还会声明产品特定信息,例如名称、品牌和型号。
        # Inherit from the common Open Source product configuration
        $(call inherit-product, $(SRC_TARGET_DIR)/product/core_64_bit.mk)
        $(call inherit-product, $(SRC_TARGET_DIR)/product/aosp_base_telephony.mk)
    
        PRODUCT_NAME := aosp_marlin
        PRODUCT_DEVICE := marlin
        PRODUCT_BRAND := Android
        PRODUCT_MODEL := AOSP on msm8996
        PRODUCT_MANUFACTURER := Google
        PRODUCT_RESTRICT_VENDOR_FILES := true
    
        PRODUCT_COPY_FILES += device/google/marlin/fstab.common:$(TARGET_COPY_OUT_VENDOR)/etc/fstab.marlin
    
        $(call inherit-product, device/google/marlin/device-marlin.mk)
        $(call inherit-product-if-exists, vendor/google_devices/marlin/device-vendor-marlin.mk)
    
        PRODUCT_PACKAGES += \
            Launcher3QuickStep \
            WallpaperPicker
        

    如需了解可添加到 Makefile 的其他产品特定变量,请参阅设置产品定义变量

  4. 创建一个指向产品的 Makefile 的 AndroidProducts.mk 文件。在此示例中,仅需要产品定义 Makefile。以下示例来自于 device/google/marlin/AndroidProducts.mk(该文件同时包含 marlin (Pixel) 和 sailfish (Pixel XL),它们共享大部分配置):
        PRODUCT_MAKEFILES := \
        	$(LOCAL_DIR)/aosp_marlin.mk \
        	$(LOCAL_DIR)/aosp_sailfish.mk
    
        COMMON_LUNCH_CHOICES := \
        	aosp_marlin-userdebug \
        	aosp_sailfish-userdebug
        
  5. 创建一个包含主板特定配置的 BoardConfig.mk Makefile。有关示例,请查看 device/google/marlin/BoardConfig.mk
  6. 创建一个 vendorsetup.sh 文件,以便将您的产品(“午餐套餐”)与构建变体(使用短划线将两者分隔开)一起添加到版本中。例如:
        add_lunch_combo <product-name>-userdebug
        
  7. 这时,您就可以基于同一设备创建更多产品变体了。

设置产品定义变量

产品特定变量在产品的 Makefile 中进行定义。下表显示了在产品定义文件中维护的部分变量。

变量 说明 示例
PRODUCT_AAPT_CONFIG 创建软件包时使用的 aapt 配置。
PRODUCT_BRAND 对软件进行自定义所针对的品牌(如果有),例如运营商。
PRODUCT_CHARACTERISTICS 用于允许向软件包中添加变体特定资源的 aapt 特性。 tabletnosdcard
PRODUCT_COPY_FILES 字词列表,如 source_path:destination_path。在构建相应产品时,应将源路径下的文件复制到目标路径。config/makefile 中定义了针对复制步骤的规则。
PRODUCT_DEVICE 工业设计的名称。这也是主板名称,构建系统会使用它来查找 BoardConfig.mk tuna
PRODUCT_LOCALES 以空格分隔的列表,用于列出由双字母语言代码和双字母国家/地区代码组成的代码对,以便说明针对用户的一些设置,例如界面语言和时间、日期以及货币格式。PRODUCT_LOCALES 中列出的第一个语言区域会用作产品的默认语言区域。 en_GB de_DE es_ES fr_CA
PRODUCT_MANUFACTURER 制造商的名称。 acme
PRODUCT_MODEL 最终产品的最终用户可见名称。
PRODUCT_NAME 总体产品的最终用户可见名称,将显示在设置 > 关于屏幕中。
PRODUCT_OTA_PUBLIC_KEYS 产品的无线下载 (OTA) 公钥列表。
PRODUCT_PACKAGES 要安装的 APK 和模块列表。 日历联系人
PRODUCT_PACKAGE_OVERLAYS 指明是使用默认资源还是添加任何产品特定叠加层。 vendor/acme/overlay
PRODUCT_PROPERTY_OVERRIDES 系统属性分配(采用 "key=value" 格式)列表。

设置 ANDROID_VENDOR_KEYS 以通过 USB 进行连接

借助 ANDROID_VENDOR_KEYS 环境变量,设备制造商可以通过 adb 访问正式版。为每个版本生成每台设备都可以接受的密钥并将其存储在内部(如存储在 vendor/oem-name/security/adb/),然后通过 ANDROID_VENDOR_KEYSadb 使用这些规范密钥,而不是随机密钥。

使用 ANDROID_VENDOR_KEYS 环境变量指向生成的加密用 adb 公钥和私钥所在的目录。私钥存储在 file 中,公钥存储在 file.pub 中。ANDROID_VENDOR_KEYS 环境变量指向存储生成的密钥对的文件或目录。

ANDROID_VENDOR_KEYS 变量被设为一个文件或目录,其中包含使用 adb keygen 文件命令生成的 2048 位 RSA 身份验证密钥对。这些密钥对是对 ADB 服务器生成的 RSA 密钥对的补充。首次使用 adb 通过 USB 进行连接时,需要 RSA 密钥对。

您必须接受主机的 RSA 密钥,才能明确授予 adb 对设备的访问权限。默认情况下,ADB 服务器生成的密钥对以 adbkey(私钥)和 adbkey.pub(公钥)的形式存储在以下密钥存储库目录中。

对于文件位置,在 macOS 上,文件位置通常为 $HOME/.android。在 Windows 上,文件位置为 %USERPROFILE%\.android;在 Linux 上,文件位置为 $home\.android。在 Windows 上,RSA 身份验证密钥也可以在 C:\Windows\System32\config\systemprofile\.android 中。

当 ADB 服务器需要密钥时,它会先搜索 ADB 服务器密钥存储库目录。如果找不到任何密钥,它会接着检查 ANDROID_VENDOR_KEYS 环境变量。如果还是找不到任何密钥,本地 ADB 服务器会生成一个新密钥对,并将其保存在 ADB 服务器密钥存储库目录中。