启用 VNDK

供应商原生开发套件 (VNDK) 需要对代码库进行多项更改,以分隔供应商和系统之间的关注点。请按照以下指南在供应商/OEM 代码库中启用 VNDK。

构建系统库

构建系统包含多种类型的对象,包括库(共享库、静态库或标头库)和二进制文件。

Build system libraries

图 1. 构建系统库。

  • core 库由系统映像在系统映像上使用。这些库不能由 vendorvendor_availablevndkvndk-sp 库使用。
    cc_library {
        name: "libThatIsCore",
        ...
    }
  • vendor-only(或 proprietary)库由供应商映像在供应商映像上使用。
    cc_library {
        name: "libThatIsVendorOnly",
        proprietary: true,
        # or: vendor: true, # (for things in AOSP)
        ...
    }
  • vendor_available 库由供应商映像在供应商映像上使用(可能包含 core 的副本)。
    cc_library {
        name: "libThatIsVendorAvailable",
        vendor_available: true,
        ...
    }
  • vndk 库由供应商映像在系统映像上使用。
    cc_library {
        name: "libThatIsVndk",
        vendor_available: true,
        vndk: {
            enabled: true,
        }
        ...
    }
  • vndk-sp 库由供应商映像使用,也由系统映像间接使用。
    cc_library {
        name: "libThatIsVndkSp",
        vendor_available: true,
        vndk: {
            enabled: true,
            support_system_process: true,
        }
        ...
    }
  • llndk 库由系统映像和供应商映像共同使用。
    cc_library {
        name: "libThatIsLlndk",
        llndk: {
            symbol_file: "libthatisllndk.map.txt"
        }
        ...
    }

当库被标记为 vendor_available:true 时,它会被构建两次

  • 一次用于平台(因此安装到 /system/lib
  • 一次用于供应商(因此安装到 /vendor/lib 或 VNDK APEX)

库的供应商版本使用 -D__ANDROID_VNDK__ 构建。使用此标志会停用未来 Android 版本中可能发生重大更改的私有系统组件。此外,不同的库会导出不同的标头集(例如 liblog)。目标的供应商变体的特定选项可以在 Android.bp 文件中指定,位置为:

target: { vendor: { … } }

为代码库启用 VNDK

要为代码库启用 VNDK,请执行以下操作:

  1. 通过计算 vendor.imgsystem.img 分区所需的尺寸来确定资格。
  2. 启用 BOARD_VNDK_VERSION=current。您可以添加到 BoardConfig.mk 或使用它直接构建组件(例如,m -j BOARD_VNDK_VERSION=current MY-LIB)。

启用 BOARD_VNDK_VERSION=current 后,构建系统会强制执行以下依赖项和标头要求。

管理依赖项

依赖于 core 组件(该组件在 vndk 中或作为 vendor 对象不存在)的 vendor 对象必须使用以下选项之一来解决

  • 可以移除依赖项。
  • 如果 core 组件归 vendor 所有,则可以将其标记为 vendor_availablevendor
  • 可以将使核心对象成为 vndk 一部分的更改向上游提交到 Google。

此外,如果 core 组件依赖于 vendor 组件,则必须将 vendor 组件制作为 core 组件,或者必须以其他方式移除依赖项(例如,通过移除依赖项或通过将依赖项移至 vendor 组件)。

管理标头

必须移除全局标头依赖项,以使构建系统知道是否使用 -D__ANDROID_VNDK__ 构建标头。例如,仍然可以使用标头库 libutils_headers 访问 libutils 标头(例如 utils/StrongPointer.h)。

某些标头(例如 unistd.h)不能再以传递方式包含,但可以在本地包含。

最后,private/android_filesystem_config.h 的公共部分已移至 cutils/android_filesystem_config.h。要管理这些标头,请执行以下操作之一:

  • 通过尽可能将所有 AID_* 宏替换为 getgrnam/ getpwnam 调用,移除对 private/android_filesystem_config.h 的依赖项。例如:
    • (uid_t)AID_WIFI 变为 getpwnam("wifi")->pw_uid
    • (gid_t)AID_SDCARD_R 变为 getgrnam("sdcard_r")->gr_gid
    有关详情,请参阅 private/android_filesystem_config.h
  • 对于硬编码的 AIS,请包含 cutils/android_filesystem_config.h