Android shared libraries evolve from time to time. Keeping prebuilt binaries up-to-date requires considerable effort. In Android 9 or earlier, the prebuilt binaries that depend on removed libraries or ABIs only fail to link at run-time. Developers have to trace the logs to find the outdated prebuilt binaries. In Android 10, a symbol-based ABI usages checker is introduced. The checker can detect outdated prebuilt binaries at build-time, so that shared library developers can know which prebuilt binaries might be broken by their change and which prebuilt binaries must be re-built.
Symbol-based ABI usages checker
The symbol-based ABI usages checker emulates the Android dynamic linker on host. The checker links the prebuilt binary with the dependencies of the prebuilt binary and checks whether all undefined symbols are resolved.
First, the checker checks the target architecture of the prebuilt binary. If the prebuilt binary does not target ARM, AArch64, x86, or x86-64 architecture, the checker skips the prebuilt binary.
Second, the dependencies of the prebuilt binary must be listed in
LOCAL_SHARED_LIBRARIES
oder shared_libs
. The build system resolves the module
names to the matching variant (i.e. core
vs. vendor
) of the shared
libraries.
Third, the checker compares the DT_NEEDED
entries to LOCAL_SHARED_LIBRARIES
oder shared_libs
. In particular, the checker extracts the DT_SONAME
entry from
each shared libraries and compares these DT_SONAME
with the DT_NEEDED
entries recorded in the prebuilt binary. If there is a mismatch, an error
message is emitted.
Fourth, the checker resolves the undefined symbols in the prebuilt binary. Those
undefined symbols must be defined in one of the dependencies and the symbol
binding must be either GLOBAL
oder WEAK
. If an undefined symbol cannot be
resolved, an error message is emitted.
Prebuilts module properties
Dependencies of the prebuilt binary must be specified in one of the following:
- Android.bp:
shared_libs: ["libc", "libdl", "libm"],
- Android.mk:
LOCAL_SHARED_LIBRARIES := libc libdl libm
If the prebuilt binary is designed to have some unresolvable undefined symbols, specify one of the following:
- Android.bp:
allow_undefined_symbols: true,
- Android.mk:
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
To have the prebuilt binary skip the ELF file check, specify one of the following:
- Android.bp:
check_elf_files: false,
- Android.mk:
LOCAL_CHECK_ELF_FILES := false
Run the checker
The checker covers all ELF prebuilt modules during the Android build process.
To run the checker alone for faster turnaround times:
m check-elf-files
ABI error fixer
The automatic fixer can help resolve ABI check errors. Simply run the fixer with
the Android.bp / Android.mk as input, and the fixer would print the suggested
fix to stdout. Optionally, run the fixer with the --in-place
option to
directly update the Android.bp / Android.mk with the suggested fix.
For 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>
For 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>