预构建 ABI 使用情况检查工具

Android 共享库会不时发生变动,因此,使预构建二进制文件保持最新状态需要投入大量的努力。在 Android 9 或更低版本中,依赖于已移除的库或 ABI 的预构建二进制文件仅在运行时无法成功链接。开发者必须在日志中查找过时的预构建二进制文件。Android 10 中引入了基于符号的 ABI 使用情况检查工具。该检查工具可以在构建时检测过时的预构建二进制文件,以便共享库开发者了解哪些预构建二进制文件可能会因其更改而出现问题,以及哪些预构建二进制文件必须重新构建。

基于符号的 ABI 使用情况检查工具

基于符号的 ABI 使用情况检查工具可模拟主机上的 Android 动态链接器。该检查工具会将预构建二进制文件与其依赖项关联起来,并检查所有未定义的符号是否均已解析。

首先,该检查工具会检查预构建二进制文件的目标架构。如果预构建二进制文件不以 ARM、AArch64、x86 或 x86-64 架构为目标,检查工具将跳过它。

其次,必须在 LOCAL_SHARED_LIBRARIESshared_libs 中列出预构建二进制文件的依赖项。构建系统会将模块名称解析为共享库的匹配变体(即 corevendor)。

第三,该检查工具会将 DT_NEEDED 条目与 LOCAL_SHARED_LIBRARIESshared_libs 进行比较。具体来说,该检查工具会从每个共享库中提取 DT_SONAME 条目,并将这些 DT_SONAME 与预构建二进制文件中记录的 DT_NEEDED 条目进行比较。如果存在不匹配,系统会发出错误消息。

第四,该检查工具会解析预构建二进制文件中未定义的符号。这些未定义的符号必须在一个依赖项中进行定义,并且符号绑定必须为 GLOBALWEAK。如果无法解析某个未定义的符号,系统会发出错误消息。

预构建模块属性

必须在下列两项的其中之一指定预构建二进制文件的依赖项:

  • Android.bp: shared_libs: ["libc", "libdl", "libm"],
  • Android.mk: LOCAL_SHARED_LIBRARIES := libc libdl libm

如果预构建二进制文件被设计为含有一些无法解析的未定义符号,请指定以下内容之一:

  • Android.bp: allow_undefined_symbols: true,
  • Android.mk: LOCAL_ALLOW_UNDEFINED_SYMBOLS := true

要使预构建二进制文件跳过 ELF 文件检查,请指定以下内容之一:

  • Android.bp: check_elf_files: false,
  • Android.mk: LOCAL_CHECK_ELF_FILES := false

运行检查工具

该检查工具在 Android 构建流程中涵盖所有 ELF 预构建模块。

如需单独运行该检查工具以缩短周转时间,请运行以下命令:

m check-elf-files

ABI 错误修复程序

该自动修复程序有助于解决 ABI 检查错误。只需使用 Android.bp/Android.mk 作为输入来运行修复程序,然后该修复程序就会将建议的修正方法输出到 stdout。(可选)使用 --in-place 选项运行修复程序,以便使用建议的修正方法直接更新 Android.bp/Android.mk。

对于 Android.bp,请运行以下代码:

m fix_android_bp_prebuilt
# Print the fixed Android.bp to stdout.
fix_android_bp_prebuilt <path-to-Android.bp>
# Update the Android.bp in place.
fix_android_bp_prebuilt --in-place <path-to-Android.bp>

对于 Android.mk,请运行以下代码:

m fix_android_mk_prebuilt
# Print the fixed Android.mk to stdout.
fix_android_mk_prebuilt <path-to-Android.mk>
# Update the Android.mk in place.
fix_android_mk_prebuilt --in-place <path-to-Android.mk>