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
執行檢查工具
如要執行檢查器,請將環境變數 CHECK_ELF_FILES
設為 true
,然後執行 make check-elf-files
:
CHECK_ELF_FILES=true make check-elf-files
如要預設啟用檢查器,請將 PRODUCT_CHECK_ELF_FILES
新增至 BoardConfig.mk
:
PRODUCT_CHECK_ELF_FILES := true
在 Android 的建構程序中,系統會自動檢查預先建構項目:
make