Las bibliotecas compartidas de Android evolucionan de vez en cuando. Mantener actualizados los objetos binarios precompilados requiere un esfuerzo considerable. En Android 9 o versiones anteriores, los objetos binarios compilados previamente que dependen de las bibliotecas o ABI que se quitaron solo no se vinculan durante el tiempo de ejecución. Los desarrolladores deben hacer un seguimiento de los registros para encontrar los objetos binarios compilados previamente desactualizados. En Android 10, se incluye un verificador de usos de ABI basado en símbolos. En el momento de la compilación, el verificador puede detectar objetos binarios compilados previamente que son obsoletos para que los desarrolladores de bibliotecas compartidas puedan saber cuáles de ellos podrían estar dañados por los cambios y cuáles deben reconstruirse.
Verificador de usos de ABI basado en símbolos
El verificador de usos de ABI basado en símbolos emula el vinculador dinámico de Android en el host. El verificador vincula el binario precompilado con las dependencias del binario precompilado y verifica si se resuelven todos los símbolos no definidos.
Primero, el verificador comprueba la arquitectura de destino del objeto binario precompilado. Si el objeto binario compilado previamente no está orientado a la arquitectura ARM, AArch64, x86 o x86-64, el verificador omite el objeto binario compilado previamente.
En segundo lugar, las dependencias del objeto binario precompilado deben enumerarse en LOCAL_SHARED_LIBRARIES
o shared_libs
. El sistema de compilación resuelve los nombres de los módulos en la variante coincidente (es decir, core
frente a vendor
) de las bibliotecas compartidas.
En tercer lugar, el verificador compara las entradas de DT_NEEDED
con LOCAL_SHARED_LIBRARIES
o shared_libs
. En particular, el verificador extrae la entrada DT_SONAME
de cada biblioteca compartida y compara estas DT_SONAME
con las entradas DT_NEEDED
registradas en el objeto binario precompilado. Si hay una discrepancia, se emite un mensaje de error.
En cuarto lugar, el verificador resuelve los símbolos no definidos en el binario precompilado. Esos símbolos no definidos deben definirse en una de las dependencias, y la vinculación de símbolos debe ser GLOBAL
o WEAK
. Si no se puede resolver un símbolo no definido, se emite un mensaje de error.
Propiedades de módulos compiladas previamente
Las dependencias del objeto binario precompilado se deben especificar en una de las siguientes opciones:
- Android.bp:
shared_libs: ["libc", "libdl", "libm"],
- Android.mk:
LOCAL_SHARED_LIBRARIES := libc libdl libm
Si el objeto binario compilado previamente está diseñado para tener algunos símbolos no definidos que no se pueden resolver, especifica una de las siguientes opciones:
- Android.bp:
allow_undefined_symbols: true,
- Android.mk:
LOCAL_ALLOW_UNDEFINED_SYMBOLS := true
Para que el objeto binario precompilado omita la verificación del archivo ELF, especifica una de las siguientes opciones:
- Android.bp:
check_elf_files: false,
- Android.mk:
LOCAL_CHECK_ELF_FILES := false
Ejecuta el verificador
El verificador abarca todos los módulos ELF precompilados durante el proceso de compilación de Android.
Para ejecutar el verificador por sí solo y lograr tiempos de respuesta más rápidos, haz lo siguiente:
m check-elf-files
Corrector de errores de ABI
El corrector automático puede ayudar a resolver errores de verificación de ABI. Simplemente, ejecuta el corrector con Android.bp o Android.mk como entrada, y el corrector imprimirá la corrección sugerida en stdout. De manera opcional, ejecuta el corrector con la opción --in-place
para actualizar directamente Android.bp o Android.mk con la corrección sugerida.
Para 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>
Para 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>