VNDK 定義工具

VNDK 定義工具可協助供應商將來源樹狀結構遷移至 Android 8.0 環境。這項工具會掃描系統和供應商映像檔中的二進位檔案,然後解決依附元件問題。根據模組依附元件圖表,這項工具也能偵測 VNDK 概念的違規事項,並提供洞察資料/建議,協助您在分割區之間移動模組。如果指定通用系統映像檔 (GSI),VNDK 定義工具可以比較系統映像檔與 GSI,並判斷擴充程式庫。

本節將介紹 VNDK 定義工具的三個常用指令:

  • vndk. 計算 Android 8.0 以上版本的建構系統變通方案適用的 VNDK_SP_LIBRARIES、VNDK_SP_EXT_LIBRARIES 和 EXTRA_VENDOR_LIBRARIES。
  • check-dep。檢查從供應商模組到不符合資格的架構共用程式庫,違反規定的模組依附元件。
  • deps。列印共用程式庫和可執行檔之間的依附元件。

如要進一步瞭解進階指令用法,請參閱 VNDK 定義工具存放區中的 README.md 檔案。

vndk

vndk 子指令會從系統分割區和供應商分割區載入共用程式庫和可執行檔,然後解析模組依附元件,判斷必須複製到 /system/lib[64]/vndk-sp-${VER}/vendor/lib[64] 的程式庫。vndk 子指令的選項包括:

選項 說明
--system 指向包含系統磁碟分割區中檔案的目錄。
--vendor 指向包含位於供應商分割區中檔案的目錄。
--aosp-system 指向包含通用系統映像檔 (GSI) 中檔案的目錄。
--load-extra-deps 指向說明隱含依附元件的檔案,例如 dlopen()

舉例來說,如要計算 VNDK 程式庫集,請執行下列 vndk 子指令:

./vndk_definition_tool.py vndk \
    --system ${ANDROID_PRODUCT_OUT}/system \
    --vendor ${ANDROID_PRODUCT_OUT}/vendor \
    --aosp-system ${ANDROID_PRODUCT_OUT}/../generic_arm64_ab/system\
    --load-extra-deps dlopen.dep

以簡單的檔案格式指定額外依附元件。每一行代表一個關係,冒號前的檔案取決於冒號後的檔案。例如:

/system/lib/libart.so: /system/lib/libart-compiler.so

這行可讓 VNDK 定義工具瞭解 libart.so 依附於 libart-compiler.so

安裝目的地

VNDK 定義工具會列出下列類別的程式庫和對應的安裝目錄:

類別 目錄
vndk_sp 必須安裝到「/system/lib[64]/vndk-sp-${VER}
vndk_sp_ext 必須安裝到「/vendor/lib[64]/vndk-sp
extra_vendor_libs 必須安裝到「/vendor/lib[64]

建構系統範本

從 VNDK 定義工具收集輸出內容後,供應商可以建立 Android.mk,並填入 VNDK_SP_LIBRARIESVNDK_SP_EXT_LIBRARIESEXTRA_VENDOR_LIBRARIES,自動將程式庫複製到指定安裝目的地。

ifneq ($(filter $(YOUR_DEVICE_NAME),$(TARGET_DEVICE)),)
VNDK_SP_LIBRARIES := ##_VNDK_SP_##
VNDK_SP_EXT_LIBRARIES := ##_VNDK_SP_EXT_##
EXTRA_VENDOR_LIBRARIES := ##_EXTRA_VENDOR_LIBS_##

#-------------------------------------------------------------------------------
# VNDK Modules
#-------------------------------------------------------------------------------
LOCAL_PATH := $(call my-dir)

define define-vndk-lib
include $$(CLEAR_VARS)
LOCAL_MODULE := $1.$2
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_PREBUILT_MODULE_FILE := $$(TARGET_OUT_INTERMEDIATE_LIBRARIES)/$1.so
LOCAL_STRIP_MODULE := false
LOCAL_MULTILIB := first
LOCAL_MODULE_TAGS := optional
LOCAL_INSTALLED_MODULE_STEM := $1.so
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_RELATIVE_PATH := $3
LOCAL_VENDOR_MODULE := $4
include $$(BUILD_PREBUILT)

ifneq ($$(TARGET_2ND_ARCH),)
ifneq ($$(TARGET_TRANSLATE_2ND_ARCH),true)
include $$(CLEAR_VARS)
LOCAL_MODULE := $1.$2
LOCAL_MODULE_CLASS := SHARED_LIBRARIES
LOCAL_PREBUILT_MODULE_FILE := $$($$(TARGET_2ND_ARCH_VAR_PREFIX)TARGET_OUT_INTERMEDIATE_LIBRARIES)/$1.so
LOCAL_STRIP_MODULE := false
LOCAL_MULTILIB := 32
LOCAL_MODULE_TAGS := optional
LOCAL_INSTALLED_MODULE_STEM := $1.so
LOCAL_MODULE_SUFFIX := .so
LOCAL_MODULE_RELATIVE_PATH := $3
LOCAL_VENDOR_MODULE := $4
include $$(BUILD_PREBUILT)
endif  # TARGET_TRANSLATE_2ND_ARCH is not true
endif  # TARGET_2ND_ARCH is not empty
endef

$(foreach lib,$(VNDK_SP_LIBRARIES),\
    $(eval $(call define-vndk-lib,$(lib),vndk-sp-gen,vndk-sp,)))
$(foreach lib,$(VNDK_SP_EXT_LIBRARIES),\
    $(eval $(call define-vndk-lib,$(lib),vndk-sp-ext-gen,vndk-sp,true)))
$(foreach lib,$(EXTRA_VENDOR_LIBRARIES),\
    $(eval $(call define-vndk-lib,$(lib),vndk-ext-gen,,true)))


#-------------------------------------------------------------------------------
# Phony Package
#-------------------------------------------------------------------------------

include $(CLEAR_VARS)
LOCAL_MODULE := $(YOUR_DEVICE_NAME)-vndk
LOCAL_MODULE_TAGS := optional
LOCAL_REQUIRED_MODULES := \
    $(addsuffix .vndk-sp-gen,$(VNDK_SP_LIBRARIES)) \
    $(addsuffix .vndk-sp-ext-gen,$(VNDK_SP_EXT_LIBRARIES)) \
    $(addsuffix .vndk-ext-gen,$(EXTRA_VENDOR_LIBRARIES))
include $(BUILD_PHONY_PACKAGE)

endif  # ifneq ($(filter $(YOUR_DEVICE_NAME),$(TARGET_DEVICE)),)

check-dep

check-dep 子指令會掃描供應商模組,並檢查其依附元件。如果偵測到違規情況,就會列印違規的依附程式庫和符號用法:

./vndk_definition_tool.py check-dep \
    --system ${ANDROID_PRODUCT_OUT}/system \
    --vendor ${ANDROID_PRODUCT_OUT}/vendor \
    --tag-file eligible-list.csv \
    --module-info ${ANDROID_PRODUCT_OUT}/module-info.json \
    1> check_dep.txt \
    2> check_dep_err.txt

舉例來說,以下輸出範例顯示從 libRS_internal.solibmediandk.so 的違規依附元件:

/system/lib/libRS_internal.so
        MODULE_PATH: frameworks/rs
        /system/lib/libmediandk.so
                AImageReader_acquireNextImage
                AImageReader_delete
                AImageReader_getWindow
                AImageReader_new
                AImageReader_setImageListener

check-dep 子指令的選項包括:

選項 說明
--tag-file 必須參照符合資格的程式庫標記檔案 (如下所述),這是 Google 提供的試算表,說明架構共用程式庫的類別。
--module-info 指向 Android 建構系統產生的 module-info.json。這有助於 VNDK 定義工具將二進位模組與原始碼建立關聯。

符合資格的程式庫標記檔案

Google 會提供符合資格的 VNDK 試算表 (例如 eligible-list.csv),標記可供供應商模組使用的架構共用程式庫:

標記 說明
LL-NDK 共用程式庫具有穩定的 ABI/API,可供架構和供應商模組使用。
LL-NDK-Private LL-NDK 程式庫的私有依附元件。供應商模組不得直接存取這些程式庫。
VNDK-SP SP-HAL 架構共用程式庫依附元件。
VNDK-SP-Private 並非所有供應商模組都能直接存取的 VNDK-SP 依附元件。
VNDK 供應商模組可用的架構共用程式庫 (SP-HAL 和 SP-HAL-Dep 除外)。
VNDK-Private 並非所有供應商模組都能直接存取的 VNDK 依附元件。
FWK-ONLY 僅限架構的共用程式庫,供應商模組不得存取 (直接或間接存取皆不可)。
FWK-ONLY-RS 僅限架構的共用程式庫,供應商模組不得存取 (RS 用途除外)。

下表說明用於供應商共用程式庫的標記:

標記 說明
SP-HAL 共用程式庫,用於實作同程序 HAL。
SP-HAL-Dep SP-HAL 供應商共用程式庫依附元件 (也稱為 SP-HAL 依附元件,但不包括 LL-NDK 和 VNDK-SP)。
僅限越南盾 架構模組不得存取的架構隱藏共用程式庫。複製的延展型 VNDK 程式庫也會標示為 VND-ONLY。

標記之間的關係:

標記之間的關係。

圖 1. 標記之間的關係。

deps

如要對程式庫依附元件進行偵錯,deps 子指令會列印模組依附元件:

./vndk_definition_tool.py deps \
    --system ${ANDROID_PRODUCT_OUT}/system \
    --vendor ${ANDROID_PRODUCT_OUT}/vendor

輸出內容包含多行。沒有定位字元的行 會開始新的章節。含有 Tab 字元的行取決於前一個部分。例如:

/system/lib/ld-android.so
/system/lib/libc.so
        /system/lib/libdl.so

這項輸出內容顯示 ld-android.so 沒有依附元件,而 libc.so 依附於 libdl.so

指定 --revert 選項時,deps 子指令會列印程式庫的用法 (反向依附元件):

./vndk_definition_tool.py deps \
    --revert \
    --system ${ANDROID_PRODUCT_OUT}/system \
    --vendor ${ANDROID_PRODUCT_OUT}/vendor

例如:

/system/lib/ld-android.so
        /system/lib/libdl.so
        

這項輸出內容顯示 ld-android.solibdl.so 使用,換句話說,libdl.so 依附於 ld-android.so。此外,這項輸出內容也顯示 libdl.sold-android.so 的唯一使用者。

指定 --symbol 選項時,deps 子指令會列印使用的符號:

./vndk_definition_tool.py deps \
    --symbol \
    --system ${ANDROID_PRODUCT_OUT}/system \
    --vendor ${ANDROID_PRODUCT_OUT}/vendor
    

例如:

/system/lib/libc.so
        /system/lib/libdl.so
                android_get_application_target_sdk_version
                dl_unwind_find_exidx
                dlclose
                dlerror
                dlopen
                dlsym

這項輸出內容顯示 libc.so 依附於從 libdl.so 匯出的六個函式。如果同時指定 --symbol 選項和 --revert 選項,系統會列印使用者使用的符號。