No Android 8.1 e versões mais recentes, o sistema de build tem suporte integrado ao VNDK. Quando a compatibilidade com o VNDK estiver ativada, o sistema de compilação verificará as dependências entre módulos, cria uma variante específica do fornecedor para os módulos do fornecedor e instala esses módulos automaticamente nos diretórios designados.
Exemplo de suporte de build do VNDK
Neste exemplo, a definição do módulo Android.bp
define um
chamada libexample
. O vendor_available
indica que os módulos de framework e de fornecedor podem depender
libexample
:
Figura 1. Suporte ativado.
O executável do framework /system/bin/foo
e o fornecedor
/vendor/bin/bar
executável dependem de libexample
e
têm libexample
nas propriedades shared_libs
.
Se libexample
for usado pelos módulos do framework e pelo fornecedor
módulos, são criadas duas variantes de libexample
. A variante principal
(nomeado de acordo com libexample
) é usado por módulos de framework e o
variante do fornecedor (com o nome de libexample.vendor
) é usada pelo fornecedor
módulos. As duas variantes são instaladas em diretórios diferentes:
- A variante principal é instalada
/system/lib[64]/libexample.so
: - A variante do fornecedor é instalada no VNDK APEX porque
vndk.enabled
étrue
.
Para mais detalhes, consulte Definição do módulo.
Configurar o suporte a build
Para ativar o suporte completo ao sistema de build em um dispositivo de produto, adicione
De BOARD_VNDK_VERSION
a BoardConfig.mk
:
BOARD_VNDK_VERSION := current
Esta configuração tem efeito global: quando definida em
BoardConfig.mk
, todos os módulos estão marcados. Como não há mecanismo
adicionar um módulo ofensivo à lista de proibições ou à lista de permissões, limpe
dependências desnecessárias antes de adicionar BOARD_VNDK_VERSION
. Você
pode testar e compilar um módulo configurando BOARD_VNDK_VERSION
no
as variáveis de ambiente:
$ BOARD_VNDK_VERSION=current m module_name.vendor
Quando BOARD_VNDK_VERSION
está ativado, vários padrões globais
os caminhos de pesquisa do cabeçalho são removidos. São eles:
frameworks/av/include
frameworks/native/include
frameworks/native/opengl/include
hardware/libhardware/include
hardware/libhardware_legacy/include
hardware/ril/include
libnativehelper/include
libnativehelper/include_deprecated
system/core/include
system/media/audio/include
Se um módulo depender dos cabeçalhos desses diretórios, será necessário especificar
explicitamente as dependências com header_libs
;
static_libs
e/ou shared_libs
.
APEX do VNDK
No Android 10 e versões anteriores, os módulos com vndk.enabled
foram instalados em
/system/lib[64]/vndk[-sp]-${VER}
. No Android 11 e versões mais recentes,
As bibliotecas do VNDK são empacotadas em um formato APEX, e o nome do VNDK APEX é
com.android.vndk.v${VER}
: Dependendo da configuração do dispositivo,
O APEX do VNDK é nivelado ou não nivelado e está disponível no caminho canônico.
/apex/com.android.vndk.v${VER}
Figura 2. APEX do VNDK.
Definição do módulo
Para criar o Android com BOARD_VNDK_VERSION
, você precisa revisar o
do módulo em Android.mk
ou
Android.bp
Esta seção descreve os diferentes tipos de módulos
diversas definições de módulo relacionadas ao VNDK e verificações de dependência
implementadas no sistema de build.
Módulos do fornecedor
Os módulos do fornecedor são executáveis ou bibliotecas compartilhadas específicos do fornecedor que
precisam ser instalados em uma partição de fornecedor. Nos arquivos Android.bp
,
os módulos do fornecedor precisam definir a propriedade proprietária ou do fornecedor como true
.
Em arquivos Android.mk
, os módulos do fornecedor precisam definir
LOCAL_VENDOR_MODULE
ou LOCAL_PROPRIETARY_MODULE
para
true
.
Se BOARD_VNDK_VERSION
for definido, o sistema de build não permitirá
dependências entre os módulos do fornecedor e do framework e emitir erros se:
- um módulo sem
vendor:true
depende de um módulo comvendor:true
ou - um módulo com
vendor:true
depende da módulo diferente dellndk_library
que não temvendor:true
nemvendor_available:true
.
A verificação de dependência se aplica a header_libs
,
static_libs
e shared_libs
em
Android.bp
e até LOCAL_HEADER_LIBRARIES
,
LOCAL_STATIC_LIBRARIES
e LOCAL_SHARED_LIBRARIES
em
Android.mk
.
LL-NDK
As bibliotecas compartilhadas do LL-NDK são bibliotecas compartilhadas com ABIs estáveis. Ambas as estruturas
e módulos de fornecedor compartilham a mesma implementação e a mais recente. Para cada
biblioteca compartilhada do LL-NDK, o cc_library
contém uma
llndk
com um arquivo de símbolo:
cc_library { name: "libvndksupport", llndk: { symbol_file: "libvndksupport.map.txt", }, }
O arquivo de símbolos descreve os símbolos visíveis para os módulos do fornecedor. Exemplo:
LIBVNDKSUPPORT { global: android_load_sphal_library; # llndk android_unload_sphal_library; # llndk local: *; };
Com base no arquivo de símbolo, o sistema de compilação gera uma biblioteca compartilhada de stubs para
módulos de fornecedores, que são vinculados a essas bibliotecas ao
BOARD_VNDK_VERSION
está ativado. Um símbolo está incluído no stub
Biblioteca compartilhada somente se ela:
- não estiver definido na seção que termina com
_PRIVATE
ou;_PLATFORM
, - Não tem a tag
#platform-only
. - Não tem tags
#introduce*
ou corresponde ao alvo.
VNDK
Nos arquivos Android.bp
, cc_library
,
cc_library_static
, cc_library_shared
e
As definições do módulo cc_library_headers
oferecem suporte a três APIs relacionadas ao VNDK
propriedades: vendor_available
, vndk.enabled
, e
vndk.support_system_process
.
Se vendor_available
ou vndk.enabled
for
true
, duas variantes (principal e fornecedor) podem ser
construído. A variante principal precisa ser tratada como um módulo do framework e o fornecedor
variante deve ser tratada como um módulo de fornecedor. Se alguns módulos do framework dependerem
neste módulo, a variante principal é criada. Se alguns módulos do fornecedor
dependerem deste módulo, a variante do fornecedor é criada. O sistema de build aplica
as seguintes verificações de dependência:
- A variante principal é sempre apenas o framework e está inacessível para o fornecedor módulos.
- A variante do fornecedor está sempre inacessível para os módulos do framework.
- Todas as dependências da variante do fornecedor, que são especificadas em
header_libs
,static_libs
e/oushared_libs
, precisa serllndk_library
ou módulo comvendor_available
ouvndk.enabled
. - Se
vendor_available
fortrue
, a variante do fornecedor é acessível a todos os módulos do fornecedor. - Se
vendor_available
forfalse
, a variante do fornecedor só pode ser acessado por outros módulos VNDK ou VNDK-SP (ou seja, módulos comvendor:true
não pode vincularvendor_available:false
módulos).
O caminho de instalação padrão para cc_library
ou
cc_library_shared
é determinado pelas seguintes regras:
- A variante principal está instalada em
/system/lib[64]
. - O caminho de instalação da variante do fornecedor pode variar:
- Se
vndk.enabled
forfalse
, a variante do fornecedor está instalado no/vendor/lib[64]
. - Se
vndk.enabled
fortrue
, a variante do fornecedor está instalado no VNDK APEX(com.android.vndk.v${VER}
).
- Se
A tabela abaixo resume como o sistema de build lida com as variantes do fornecedor:
fornecedor_disponível | vndk ativado |
vndk support_same_process |
Descrições das variantes do fornecedor |
---|---|---|---|
true |
false |
false |
As variantes do fornecedor são SOMENTE VND. As bibliotecas compartilhadas são
instalado no /vendor/lib[64] . |
true |
Inválido (erro de build) | ||
true |
false |
As variantes do fornecedor são VNDK. As bibliotecas compartilhadas estão instaladas ao VNDK APEX. | |
true |
As variantes do fornecedor são VNDK-SP. As bibliotecas compartilhadas são instalado no VNDK APEX. | ||
|
|
|
Nenhuma variante de fornecedor. Este módulo é SOMENTE FWK. |
true |
Inválido (erro de build) | ||
true |
false |
As variantes do fornecedor são VNDK-Private. As bibliotecas compartilhadas são instalado no VNDK APEX. Elas não podem ser usado diretamente pelos módulos do fornecedor. | |
true |
As variantes do fornecedor são VNDK-SP-Private. As bibliotecas compartilhadas são instalado no VNDK APEX. Elas não podem ser usado diretamente pelos módulos do fornecedor. |
Extensões VNDK
As extensões do VNDK são bibliotecas compartilhadas do VNDK com outras APIs. As extensões são
instalado no /vendor/lib[64]/vndk[-sp]
(sem sufixo de versão)
e substituir as bibliotecas compartilhadas do VNDK originais no momento da execução.
Definir extensões do VNDK
No Android 9 e versões mais recentes, o Android.bp
oferece suporte nativo ao VNDK
extensões. Para criar uma extensão do VNDK, defina outro módulo com uma
vendor:true
e uma propriedade extends
:
cc_library { name: "libvndk", vendor_available: true, vndk: { enabled: true, }, } cc_library { name: "libvndk_ext", vendor: true, vndk: { enabled: true, extends: "libvndk", }, }
Um módulo com vendor:true
, vndk.enabled:true
e
As propriedades extends
definem a extensão do VNDK:
- A propriedade
extends
precisa especificar uma biblioteca compartilhada VNDK de base. (ou nome da biblioteca compartilhada VNDK-SP). - As extensões VNDK (ou extensões VNDK-SP) são nomeadas com base no módulo base
e os nomes de origem deles. Por exemplo, o binário de saída
libvndk_ext
élibvndk.so
em vez delibvndk_ext.so
- As extensões do VNDK são instaladas em
/vendor/lib[64]/vndk
. - As extensões do VNDK-SP são instaladas
/vendor/lib[64]/vndk-sp
: - As bibliotecas compartilhadas de base precisam ter
vndk.enabled:true
evendor_available:true
.
Uma extensão VNDK-SP precisa se estender de uma biblioteca compartilhada do VNDK-SP.
(vndk.support_system_process
precisa ser igual a):
cc_library { name: "libvndk_sp", vendor_available: true, vndk: { enabled: true, support_system_process: true, }, } cc_library { name: "libvndk_sp_ext", vendor: true, vndk: { enabled: true, extends: "libvndk_sp", support_system_process: true, }, }
As extensões VNDK (ou extensões VNDK-SP) podem depender de outros fornecedores compartilhados bibliotecas:
cc_library { name: "libvndk", vendor_available: true, vndk: { enabled: true, }, } cc_library { name: "libvndk_ext", vendor: true, vndk: { enabled: true, extends: "libvndk", }, shared_libs: [ "libvendor", ], } cc_library { name: "libvendor", vendor: true, }
Usar extensões VNDK
Se um módulo de fornecedor depender de APIs adicionais definidas pelas extensões do VNDK, o
precisa especificar o nome da extensão do VNDK no
Propriedade shared_libs
:
// A vendor shared library example cc_library { name: "libvendor", vendor: true, shared_libs: [ "libvndk_ext", ], } // A vendor executable example cc_binary { name: "vendor-example", vendor: true, shared_libs: [ "libvndk_ext", ], }
Se um módulo de fornecedor depender das extensões do VNDK, essas extensões do VNDK serão
instalado no /vendor/lib[64]/vndk[-sp]
automaticamente. Se um módulo
não depende mais de uma extensão do VNDK, adicione uma etapa de limpeza ao
CleanSpec.mk
para remover a biblioteca compartilhada. Exemplo:
$(call add-clean-step, rm -rf $(TARGET_OUT_VENDOR)/lib/libvndk.so)
Compilação condicional
Esta seção descreve como lidar com as diferenças sutis (por exemplo, adicionar ou remover um atributo de uma das variantes) entre os seguintes três bibliotecas compartilhadas do VNDK:
- Variante principal (por exemplo,
/system/lib[64]/libexample.so
) - A variante do fornecedor (por exemplo,
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so
) - Extensão do VNDK (por exemplo,
/vendor/lib[64]/vndk[-sp]/libexample.so
)
Sinalizações do compilador condicional
O sistema de build do Android define __ANDROID_VNDK__
para o
variantes e extensões do VNDK por padrão. É possível proteger o código
com as proteções do pré-processador C:
void all() { } #if !defined(__ANDROID_VNDK__) void framework_only() { } #endif #if defined(__ANDROID_VNDK__) void vndk_only() { } #endif
Além de __ANDROID_VNDK__
, diferentes cflags
ou
cppflags
pode ser especificado em Android.bp
. A
cflags
ou cppflags
especificado em
target.vendor
é específico para a variante do fornecedor.
Por exemplo, o Android.bp
abaixo define
libexample
e libexample_ext
:
cc_library { name: "libexample", srcs: ["src/example.c"], vendor_available: true, vndk: { enabled: true, }, target: { vendor: { cflags: ["-DLIBEXAMPLE_ENABLE_VNDK=1"], }, }, } cc_library { name: "libexample_ext", srcs: ["src/example.c"], vendor: true, vndk: { enabled: true, extends: "libexample", }, cflags: [ "-DLIBEXAMPLE_ENABLE_VNDK=1", "-DLIBEXAMPLE_ENABLE_VNDK_EXT=1", ], }
Esta é a lista de códigos de src/example.c
:
void all() { } #if !defined(LIBEXAMPLE_ENABLE_VNDK) void framework_only() { } #endif #if defined(LIBEXAMPLE_ENABLE_VNDK) void vndk() { } #endif #if defined(LIBEXAMPLE_ENABLE_VNDK_EXT) void vndk_ext() { } #endif
De acordo com esses dois arquivos, o sistema de compilação gera bibliotecas compartilhadas com os seguintes símbolos exportados:
Caminho de instalação | Símbolos exportados |
---|---|
/system/lib[64]/libexample.so |
all , framework_only |
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so |
all , vndk |
/vendor/lib[64]/vndk/libexample.so |
all , vndk , vndk_ext |
Requisitos para os símbolos exportados
O verificador de ABI VNDK
compara a ABI das variantes do fornecedor do VNDK e
Extensões VNDK para os despejos da ABI de referência em
prebuilts/abi-dumps/vndk
.
- Símbolos exportados pelas variantes do fornecedor do VNDK (por exemplo,
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so
) precisam ser idênticos aos (não aos superconjuntos) dos símbolos definidos nos despejos da ABI. - Símbolos exportados por extensões VNDK (por exemplo,
/vendor/lib[64]/vndk/libexample.so
) precisam ser superconjuntos da símbolos definidos em despejos de ABI.
Se as variantes do fornecedor do VNDK ou as extensões do VNDK não forem seguidas os requisitos acima, o verificador de ABI do VNDK emite erros de build e interrompe a ser construído.
Excluir arquivos de origem ou bibliotecas compartilhadas das variantes do fornecedor
Para excluir arquivos de origem da variante do fornecedor, adicione-os ao
exclude_srcs
. Da mesma forma, para garantir que as bibliotecas compartilhadas sejam
não vinculadas à variante do fornecedor, adicione essas bibliotecas ao
exclude_shared_libs
. Exemplo:
cc_library { name: "libexample_cond_exclude", srcs: ["fwk.c", "both.c"], shared_libs: ["libfwk_only", "libboth"], vendor_available: true, target: { vendor: { exclude_srcs: ["fwk.c"], exclude_shared_libs: ["libfwk_only"], }, }, }
Neste exemplo, a variante principal de libexample_cond_exclude
inclui o código de fwk.c
e both.c
e depende
nas bibliotecas compartilhadas libfwk_only
e libboth
. A
variante de fornecedor de libexample_cond_exclude
inclui apenas o código
de both.c
porque fwk.c
é excluído pelo
propriedade exclude_srcs
. Da mesma forma, depende apenas da Biblioteca compartilhada
libboth
porque libfwk_only
é excluído pelo
propriedade exclude_shared_libs
.
Exportar cabeçalhos de extensões VNDK
Uma extensão do VNDK pode adicionar novas classes ou funções a um VNDK compartilhado. biblioteca. Sugerimos manter essas declarações em cabeçalhos independentes, e evite alterar os cabeçalhos existentes.
Por exemplo, um novo arquivo principal
include-ext/example/ext/feature_name.h
é criado para o VNDK.
extensão libexample_ext
:
- Android.bp
- include-ext/example/ext/feature_name.h (link em inglês)
- incluir/exemplo/exemplo.h
- src/exemplo.c
- src/ext/feature_name.c (link em inglês)
Nas exportações de Android.bp
a seguir, libexample
somente include
, enquanto libexample_ext
exporta ambos
include
e include-ext
. Isso garante
feature_name.h
não serão incluídos incorretamente pelos usuários de
libexample
:
cc_library { name: "libexample", srcs: ["src/example.c"], export_include_dirs: ["include"], vendor_available: true, vndk: { enabled: true, }, } cc_library { name: "libexample_ext", srcs: [ "src/example.c", "src/ext/feature_name.c", ], export_include_dirs: [ "include", "include-ext", ], vendor: true, vndk: { enabled: true, extends: "libexample", }, }
Se não for possível separar as extensões em arquivos de cabeçalho independentes, uma
alternativa é adicionar guardas #ifdef
. No entanto, certifique-se de que todas
Os usuários da extensão VNDK adicionam as sinalizações de definição. Você pode definir
cc_defaults
para adicionar flags para definir a cflags
e vincular
bibliotecas compartilhadas com shared_libs
.
Por exemplo, para adicionar uma nova função de membro Example2::get_b()
a
extensão libexample2_ext
do VNDK, você precisa modificar a
e adicione uma proteção #ifdef
:
#ifndef LIBEXAMPLE2_EXAMPLE_H_ #define LIBEXAMPLE2_EXAMPLE_H_ class Example2 { public: Example2(); void get_a(); #ifdef LIBEXAMPLE2_ENABLE_VNDK_EXT void get_b(); #endif private: void *impl_; }; #endif // LIBEXAMPLE2_EXAMPLE_H_
Um cc_defaults
chamado libexample2_ext_defaults
está
definido para os usuários de libexample2_ext
:
cc_library { name: "libexample2", srcs: ["src/example2.cpp"], export_include_dirs: ["include"], vendor_available: true, vndk: { enabled: true, }, } cc_library { name: "libexample2_ext", srcs: ["src/example2.cpp"], export_include_dirs: ["include"], vendor: true, vndk: { enabled: true, extends: "libexample2", }, cflags: [ "-DLIBEXAMPLE2_ENABLE_VNDK_EXT=1", ], } cc_defaults { name: "libexample2_ext_defaults", shared_libs: [ "libexample2_ext", ], cflags: [ "-DLIBEXAMPLE2_ENABLE_VNDK_EXT=1", ], }
Os usuários de libexample2_ext
podem simplesmente incluir
libexample2_ext_defaults
na defaults
:
cc_binary { name: "example2_user_executable", defaults: ["libexample2_ext_defaults"], vendor: true, }
Pacotes de produtos
No sistema de build do Android, a variável PRODUCT_PACKAGES
especifica os executáveis, bibliotecas compartilhadas ou pacotes que devem ser
instalado no dispositivo. As dependências transitivas do objeto especificado
módulos também são implicitamente instalados no dispositivo.
Se BOARD_VNDK_VERSION
estiver ativado, os módulos com
vendor_available
ou vndk.enabled
ganham oferta especial
tratamento. Se um módulo de framework depender de um módulo com
vendor_available
ou vndk.enabled
, a variante principal
está incluído no conjunto de instalação transitiva. Se um módulo de fornecedor
depende de um módulo com vendor_available
, a variante do fornecedor é
incluído no conjunto de instalações transitivas. No entanto, as variantes de módulos do fornecedor
com vndk.enabled
são instalados, quer sejam usados ou não pelos módulos do fornecedor.
Quando as dependências são invisíveis para o sistema de build (por exemplo, bibliotecas compartilhadas).
que pode ser aberto com dlopen()
durante a execução), especifique
os nomes dos módulos em PRODUCT_PACKAGES
para instalar esses módulos
explicitamente.
Se um módulo tiver vendor_available
ou vndk.enabled
:
o nome do módulo representa a variante principal dele. Para especificar explicitamente o
variante do fornecedor em PRODUCT_PACKAGES
, anexe um .vendor
ao nome do módulo. Exemplo:
cc_library { name: "libexample", srcs: ["example.c"], vendor_available: true, }
Neste exemplo, libexample
significa
/system/lib[64]/libexample.so
e libexample.vendor
significa /vendor/lib[64]/libexample.so
. Para instalar
/vendor/lib[64]/libexample.so
, adicionar libexample.vendor
para PRODUCT_PACKAGES
:
PRODUCT_PACKAGES += libexample.vendor