Android 共享库会不时演变。保持预构建二进制文件最新需要相当大的努力。在 Android 9 或更早版本中,依赖于已删除库或 ABI 的预构建二进制文件仅在运行时链接失败。开发人员必须跟踪日志以查找过时的预构建二进制文件。在 Android 10 中,引入了基于符号的 ABI 用法检查工具。该检查工具可以在构建时检测过时的预构建二进制文件,以便共享库开发人员可以知道哪些预构建二进制文件可能会因其更改而损坏,以及哪些预构建二进制文件必须重新构建。
基于符号的 ABI 用法检查工具
基于符号的 ABI 用法检查工具在主机上模拟 Android 动态链接器。该检查工具将预构建二进制文件与预构建二进制文件的依赖项链接起来,并检查是否所有未定义的符号都已解析。
首先,检查工具检查预构建二进制文件的目标架构。如果预构建二进制文件不以 ARM、AArch64、x86 或 x86-64 架构为目标,则检查工具会跳过该预构建二进制文件。
其次,预构建二进制文件的依赖项必须在 LOCAL_SHARED_LIBRARIES
或 shared_libs
中列出。构建系统将模块名称解析为共享库的匹配变体(即 core
与 vendor
)。
第三,检查工具将 DT_NEEDED
条目与 LOCAL_SHARED_LIBRARIES
或 shared_libs
进行比较。特别是,检查工具从每个共享库中提取 DT_SONAME
条目,并将这些 DT_SONAME
与预构建二进制文件中记录的 DT_NEEDED
条目进行比较。如果存在不匹配,则会发出错误消息。
第四,检查工具解析预构建二进制文件中的未定义符号。这些未定义的符号必须在依赖项之一中定义,并且符号绑定必须是 GLOBAL
或 WEAK
。如果无法解析未定义的符号,则会发出错误消息。
预构建模块属性
预构建二进制文件的依赖项必须在以下任一项中指定
- 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>