Ferramenta de definição de VNDK

A ferramenta de definição do VNDK ajuda os fornecedores a migrar a árvore de origem para um ambiente do Android 8.0. Essa ferramenta verifica arquivos binários nas imagens do sistema e do fornecedor e resolve as dependências. Com base no gráfico de dependência de módulos, a ferramenta também pode detectar violações de conceitos do VNDK e fornecer insights/sugestões para mover módulos entre partições. Se uma imagem genérica do sistema (GSI) for especificada, a ferramenta de definição do VNDK poderá comparar a imagem do sistema com a GSI e determinar as bibliotecas estendidas.

Esta seção aborda três comandos usados com frequência para a ferramenta de definição do VNDK:

  • vndk. Computar VNDK_SP_LIBRARIES, VNDK_SP_EXT_LIBRARIES e EXTRA_VENDOR_LIBRARIES para a solução alternativa do sistema de build no Android 8.0 e versões mais recentes.
  • check-dep. Verifique as dependências de módulo em violação dos módulos do fornecedor para bibliotecas compartilhadas de framework não qualificadas.
  • deps. Imprime as dependências entre as bibliotecas compartilhadas e os executáveis.

Para mais detalhes sobre o uso avançado de comandos, consulte o arquivo README.md no repositório da ferramenta de definição do VNDK.

vndk

O subcomando vndk carrega as bibliotecas compartilhadas e executáveis da partição do sistema e das partições do fornecedor e, em seguida, resolve as dependências de módulo para determinar as bibliotecas que precisam ser copiadas para /system/lib[64]/vndk-sp-${VER} e /vendor/lib[64]. As opções para o subcomando vndk incluem:

Opção Descrição
--system Aponte para um diretório que contenha os arquivos que residem na partição do sistema.
--vendor Aponte para um diretório que contenha os arquivos que residem em uma partição do fornecedor.
--aosp-system Aponte para um diretório que contenha os arquivos que residem na imagem genérica do sistema (GSI).
--load-extra-deps Aponte para um arquivo que descreva as dependências implícitas, como dlopen().

Por exemplo, para calcular os conjuntos de bibliotecas do VNDK, execute o seguinte subcomando 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

Especifique dependências extras com um formato de arquivo simples. Cada linha representa uma relação, com o arquivo antes do dois-ponto dependendo do arquivo depois do dois-ponto. Exemplo:

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

Essa linha informa à ferramenta de definição do VNDK que libart.so depende de libart-compiler.so.

Destino da instalação

A ferramenta de definição do VNDK lista bibliotecas e diretórios de instalação correspondentes para as seguintes categorias:

Categoria Diretório
vndk_sp Precisa ser instalado em /system/lib[64]/vndk-sp-${VER}
vndk_sp_ext Precisa ser instalado em /vendor/lib[64]/vndk-sp
extra_vendor_libs Precisa ser instalado em /vendor/lib[64]

Criar modelos de sistema

Depois de coletar as saídas da ferramenta de definição do VNDK, um fornecedor pode criar um Android.mk e preencher VNDK_SP_LIBRARIES, VNDK_SP_EXT_LIBRARIES e EXTRA_VENDOR_LIBRARIES para automatizar o processo de cópia de bibliotecas para o destino de instalação designado.

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

O subcomando check-dep verifica os módulos do fornecedor e suas dependências. Se ele detectar violações, ele vai mostrar a biblioteca dependente que viola e os usos de símbolo:

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

Por exemplo, a saída de exemplo a seguir mostra uma dependência de violação de libRS_internal.so para 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

As opções para o subcomando check-dep incluem:

Opção Descrição
--tag-file Precisa se referir a um arquivo de tag de biblioteca qualificado (descrito abaixo), que é uma planilha fornecida pelo Google que descreve categorias de bibliotecas compartilhadas do framework.
--module-info Indica o module-info.json gerado pelo sistema de build do Android. Ela ajuda a ferramenta de definição do VNDK a associar módulos binários ao código-fonte.

Arquivo de tag de biblioteca qualificado

O Google fornece uma planilha do VNDK qualificada (por exemplo, eligible-list.csv) que marca as bibliotecas compartilhadas do framework que podem ser usadas por módulos de fornecedores:

Tag Descrição
LL-NDK Bibliotecas compartilhadas com ABIs/APIs estáveis que podem ser usadas por módulos de fornecedores e de framework.
LL-NDK-Private Dependências privadas de bibliotecas LL-NDK. Os módulos do fornecedor não podem acessar essas bibliotecas diretamente.
VNDK-SP Dependências de bibliotecas compartilhadas do framework SP-HAL.
VNDK-SP-Private Dependências do VNDK-SP que não são diretamente acessíveis a todos os módulos do fornecedor.
VNDK Bibliotecas compartilhadas do framework que estão disponíveis para módulos do fornecedor (exceto SP-HAL e SP-HAL-Dep).
VNDK-Private Dependências do VNDK que não são diretamente acessíveis a todos os módulos do fornecedor.
FWK-ONLY Bibliotecas compartilhadas exclusivas do framework que não podem ser acessadas por módulos do fornecedor (diretamente ou indiretamente).
FWK-ONLY-RS Bibliotecas compartilhadas exclusivas do framework que não podem ser acessadas por módulos do fornecedor (exceto para usos de RS).

A tabela a seguir descreve as tags usadas para bibliotecas compartilhadas do fornecedor:

Tag Descrição
SP-HAL Bibliotecas compartilhadas de implementação do HAL do mesmo processo.
SP-HAL-Dep Dependências de bibliotecas compartilhadas do fornecedor do SP-HAL (também chamadas de dependências do SP-HAL, excluindo LL-NDK e VNDK-SP).
VND-ONLY Bibliotecas compartilhadas invisíveis ao framework que não podem ser acessadas por módulos do framework. As bibliotecas estendidas do VNDK copiadas também são marcadas como VND-ONLY.

Relações entre tags:

Relações entre tags.

Figura 1. Relações entre tags.

dependências

Para depurar as dependências da biblioteca, o subcomando deps imprime as dependências do módulo:

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

A saída consiste em várias linhas. A linha sem um caractere de tabulação inicia uma nova seção. A linha com um caractere de tabulação depende da seção anterior. Exemplo:

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

Essa saída mostra que ld-android.so não tem dependência e libc.so depende de libdl.so.

Ao especificar a opção --revert, o subcomando deps imprime os usos de bibliotecas (dependências invertidas):

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

Exemplo:

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

Essa saída mostra que ld-android.so é usado por libdl.so, ou em outras palavras, libdl.so depende de ld-android.so. Além disso, essa saída mostra que libdl.so é o único usuário de ld-android.so.

Ao especificar a opção --symbol, o subcomando deps imprime os símbolos usados:

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

Exemplo:

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

Essa saída mostra que libc.so depende de seis funções exportadas de libdl.so. Se as opções --symbol e --revert forem especificadas, os símbolos usados pelo usuário serão impressos.