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>