VNDK 定義ツール

VNDK 定義ツールは、ベンダーがソースツリーを Android 8.0 環境へ移行するのに役立ちます。このツールは、システム内バイナリ ファイルとベンダー イメージをスキャンし、依存関係を解決します。また、モジュール依存関係グラフに基づいて、VNDK コンセプトに対する違反を検出し、パーティション間でモジュールを移動するためのインサイトやアドバイスを提供します。Generic System Image(GSI)を指定した場合、VNDK 定義ツールはシステム イメージを GSI と比較し、拡張ライブラリを特定できます。

このセクションでは、VNDK 定義ツールでよく使用される 3 つのコマンドについて説明します。

  • 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 Generic System Image(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

この行は、libart.solibart-compiler.so に依存していることを VNDK 定義ツールに認識させます。

インストール先

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.so から libmediandk.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 Same-process HAL 実装共有ライブラリ。
SP-HAL-Dep SP-HAL ベンダー共有ライブラリの依存関係(LL-NDK と VNDK-SP を除く SP-HAL の依存関係)。
VND-ONLY フレームワーク モジュールがアクセスできないフレームワーク非表示の共有ライブラリ。コピーされた拡張 VNDK ライブラリも VND-ONLY としてタグ付けされます。

タグの間の関係:

タグの間の関係。
図 1. タグの間の関係。

deps

ライブラリの依存関係をデバッグするために、deps サブコマンドがモジュールの依存関係を出力します。

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

出力は複数の行で構成されます。タブ文字のない行は新しいセクションを開始します。タブ文字のある行は、前のセクションに依存します。次に例を示します。

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

この出力は、ld-android.so は依存関係がなく、libc.solibdl.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
        

この出力は、libdl.sold-android.so を使用していること、つまり、libdl.sold-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.solibdl.so からエクスポートされた 6 つの関数に依存していることを示しています。--symbol 設定と --revert 設定の両方を指定した場合、ユーザーが使用するシンボルを出力します。