Narzędzie do definicji VNDK

Narzędzie do definiowania VNDK pomaga dostawcom przenieść drzewo źródłowe do środowiska Androida 8.0. To narzędzie skanuje pliki binarne w systemie i obrazuje dostawców, a następnie rozwiązuje zależności. Na podstawie grafu zależności modułów narzędzie może też wykrywać naruszenia koncepcji VNDK i podawać statystyki oraz sugestie dotyczące przenoszenia modułów między partycjami. Jeśli podano ogólny obraz systemu (GSI), narzędzie do definiowania VNDK może porównać obraz systemu z GSI i określić rozszerzone biblioteki.

W tej sekcji omówiono 3 często używane polecenia narzędzia do definiowania VNDK:

  • vndk. Oblicz zmienne VNDK_SP_LIBRARIES, VNDK_SP_EXT_LIBRARIES i EXTRA_VENDOR_LIBRARIES, aby obejść problemy z systemem kompilacji w Androidzie 8.0 i nowszych.
  • check-dep. Sprawdź zależności modułów, które naruszają zasady, z modułów dostawców do nieodpowiednich bibliotek wspólnych frameworka.
  • deps. Wydrukuj zależności między bibliotekami współdzielonymi a plikami wykonywalnymi.

Więcej informacji o zaawansowanym stosowaniu poleceń znajdziesz w pliku README.md w repozytorium narzędzia VNDK Definition Tool.

vndk

Podkomenda vndk wczytuje wspólne biblioteki i pliki wykonywalne z partycji systemowej oraz partycji dostawców, a potem rozwiązuje zależności modułów, aby określić biblioteki, które należy skopiować do /system/lib[64]/vndk-sp-${VER}/vendor/lib[64]. Opcje polecenia vndk:

Option Opis
--system Wskazać katalog zawierający pliki znajdujące się na partycji systemowej.
--vendor Wskazać katalog zawierający pliki znajdujące się w partycji dostawcy.
--aosp-system Wskazać katalog zawierający pliki, które znajdują się w uniwersalnym obrazie systemu (GSI).
--load-extra-deps Wskazać plik, który opisuje ukryte zależności, np. dlopen().

Aby na przykład obliczyć zestawy bibliotek VNDK, uruchom to podpolecenie 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

określić dodatkowe zależności za pomocą prostego formatu pliku. Każda linia reprezentuje relację, przy czym plik przed dwukropkiem zależy od pliku po dwukropku. Przykład:

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

Ten wiersz informuje narzędzie do definiowania VNDK, że libart.so zależy od libart-compiler.so.

Miejsce docelowe instalacji

Narzędzie do definiowania VNDK zawiera listę bibliotek i odpowiednich katalogów instalacji w tych kategoriach:

Kategoria Katalog
vndk_sp Musi być zainstalowany na /system/lib[64]/vndk-sp-${VER}
vndk_sp_ext Musi być zainstalowany na /vendor/lib[64]/vndk-sp
extra_vendor_libs Musi być zainstalowany na /vendor/lib[64]

Tworzenie szablonów systemowych

Po zebraniu danych wyjściowych z narzędzia do definiowania VNDK sprzedawca może utworzyć plik Android.mk i wypełnić pola VNDK_SP_LIBRARIES, VNDK_SP_EXT_LIBRARIESEXTRA_VENDOR_LIBRARIES, aby zautomatyzować proces kopiowania bibliotek do wyznaczonego miejsca docelowego instalacji.

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

Podkomenda check-dep skanuje moduły dostawcy i sprawdza ich zależności. Jeśli wykryje naruszenia, wypisuje zależne biblioteki i użycia symboli, które je powodują:

./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

Na przykład poniższy przykładowy wynik pokazuje zależność naruszającą regułę z libRS_internal.so do 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

Opcje polecenia check-dep:

Option Opis
--tag-file Musi odnosić się do kwalifikującego się pliku tagów biblioteki (opisanego poniżej), czyli arkusza kalkulacyjnego udostępnionego przez Google, który opisuje kategorie bibliotek udostępnianych w ramach frameworku.
--module-info Wskazuje na module-info.json wygenerowany przez system Android Build System. Pomaga narzędziu do definiowania VNDK w kojarzeniu modułów binarnych z kodem źródłowym.

Kwalifikujący się plik tagów biblioteki

Google udostępnia arkusz kalkulacyjny z odpowiednimi bibliotekami VNDK (np. eligible-list.csv), który zawiera tagi bibliotek wspólnych frameworku, których można używać w modułach dostawców:

Tag Opis
LL-NDK udostępnione biblioteki ze stabilnymi interfejsami ABI/API, których mogą używać zarówno frameworki, jak i moduły dostawców;
LL-NDK-Private prywatne zależności bibliotek LL-NDK. Moduł dostawcy nie może mieć bezpośredniego dostępu do tych bibliotek.
VNDK-SP Biblioteki udostępnione w ramach frameworku SP-HAL.
VNDK-SP-Private zależności VNDK-SP, do których nie mają bezpośredniego dostępu wszystkie moduły dostawcy.
VNDK Biblioteki wspólne frameworku dostępne dla modułów dostawców (z wyjątkiem SP-HAL i SP-HAL-Dep).
VNDK-Private zależności VNDK, do których nie mają bezpośredniego dostępu wszystkie moduły dostawcy.
FWK-ONLY biblioteki wspólne tylko do frameworku, do których nie mogą mieć dostępu moduły dostawcy (ani bezpośrednio, ani pośrednio).
FWK-ONLY-RS Biblioteki współdzielone tylko do frameworku, do których nie mogą mieć dostępu moduły dostawcy (z wyjątkiem zastosowań RS).

W tabeli poniżej opisano tagi używane w przypadku bibliotek udostępnianych przez dostawców:

Tag Opis
SP-HAL biblioteki udostępnione w ramach tego samego procesu implementacji HAL;
SP-HAL-Dep zależności bibliotek udostępnionych dostawcy SP-HAL (nazywane też zależnościami SP-HAL), z wyjątkiem LL-NDK i VNDK-SP;
VND-ONLY biblioteki współużytkowane, które są niewidoczne dla frameworka i do których nie mogą mieć dostępu moduły frameworka. Skopiowane rozszerzone biblioteki VNDK są również oznaczone jako VND-ONLY.

Relacje między tagami:

relacje między tagami.

Rysunek 1. relacje między tagami.

deps

Aby debugować zależności biblioteki, podkomenda deps wypisuje zależności modułu:

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

Dane wyjściowe zawierają wiele wierszy. Wiersz bez znaku tabulacji rozpoczyna nową sekcję. Wiersz z znakiem tabulacji zależy od poprzedniej sekcji. Przykład:

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

Wynik pokazuje, że ld-android.so nie ma zależności, a libc.so zależy od libdl.so.

Gdy podasz opcję --revert, podkomenda deps wypisuje używanie bibliotek (odwrócone zależności):

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

Przykład:

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

Wynik pokazuje, że ld-android.so jest używane przez libdl.so, czyli że libdl.so zależy od ld-android.so. Wynik pokazuje też, że libdl.so jest jedynym użytkownikiem ld-android.so.

Gdy podasz opcję --symbol, podkomenda deps wypisuje używane symbole:

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

Przykład:

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

Dane wyjściowe wskazują, że funkcja libc.so zależy od 6 funkcji wyeksportowanych z funkcji libdl.so. Jeśli zdefiniowano opcję --symbol i opcję --revert, symbole użyte przez użytkownika są drukowane.