En Android 8.1 y versiones posteriores, el sistema de compilación tiene compatibilidad integrada con VNDK. Cuándo La compatibilidad con VNDK está habilitada, el sistema de compilación verifica las dependencias entre compila una variante específica del proveedor para los módulos de proveedor y instala automáticamente esos módulos en directorios designados.
Ejemplo de compatibilidad con la compilación VNDK
En este ejemplo, la definición del módulo Android.bp
define una
biblioteca llamada libexample
. El vendor_available
indica que los módulos del framework y los módulos de los proveedores pueden depender
libexample
Figura 1: Compatibilidad habilitada
El framework ejecutable /system/bin/foo
y el proveedor
ejecutables /vendor/bin/bar
dependen de libexample
y
tienen libexample
en sus propiedades shared_libs
.
Si el proveedor y los módulos del framework usan libexample
se compilan dos variantes de libexample
. La variante principal
(con el nombre de libexample
) se usan en los módulos del framework y la
El proveedor utiliza la variante de proveedor (con el nombre libexample.vendor
).
módulos. Las dos variantes se instalan en directorios diferentes:
- La variante principal se instala en
/system/lib[64]/libexample.so
- La variante del proveedor se instala en APEX de VNDK debido a lo siguiente:
vndk.enabled
estrue
.
Para obtener más detalles, consulta la definición del módulo.
Cómo configurar la compatibilidad con compilaciones
Para habilitar la compatibilidad total con el sistema de compilación para un dispositivo de producto, agrega
De BOARD_VNDK_VERSION
a BoardConfig.mk
:
BOARD_VNDK_VERSION := current
Este parámetro de configuración tiene un efecto global: cuando se define en
BoardConfig.mk
, se verificaron todos los módulos. Como no hay un mecanismo
para incluir en la lista negra o la lista blanca
un módulo ofensivo, debes borrar todo
las dependencias innecesarias antes de agregar BOARD_VNDK_VERSION
. Tú
puedes probar y compilar un módulo configurando BOARD_VNDK_VERSION
en
tus variables de entorno:
$ BOARD_VNDK_VERSION=current m module_name.vendor
Cuando se habilita BOARD_VNDK_VERSION
, varias configuraciones globales
se quitan las rutas de búsqueda de encabezados. Por ejemplo:
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
Si un módulo depende de los encabezados de estos directorios, debes especificar
(De forma explícita) las dependencias con header_libs
,
static_libs
o shared_libs
.
APEX del VNDK
En Android 10 y versiones anteriores, los módulos con vndk.enabled
se instalaban en
/system/lib[64]/vndk[-sp]-${VER}
En Android 11 y versiones posteriores,
Las bibliotecas de VNDK se empaquetan en formato APEX y el nombre de ese formato es
com.android.vndk.v${VER}
Según la configuración del dispositivo,
VNDK APEX está plano o sin compactar, y está disponible en la ruta canónica
/apex/com.android.vndk.v${VER}
Figura 2: APEX de VNDK
Definición del módulo
Para compilar Android con BOARD_VNDK_VERSION
, debes revisar el
definición del módulo en Android.mk
o
Android.bp
En esta sección, se describen diferentes tipos de módulos
definiciones, varias propiedades de módulos relacionadas con VNDK y verificaciones de dependencias
implementadas en el sistema de compilación.
Módulos de proveedores
Los módulos de proveedor son bibliotecas compartidas o ejecutables específicos del proveedor que
debe instalarse en una partición del proveedor. En Android.bp
archivos,
Los módulos de proveedor deben establecer el proveedor o la propiedad de propiedad en true
.
En archivos Android.mk
, los módulos de proveedores deben establecer
LOCAL_VENDOR_MODULE
o LOCAL_PROPRIETARY_MODULE
para
true
Si se define BOARD_VNDK_VERSION
, el sistema de compilación no permite
las dependencias entre los módulos de proveedores y los módulos del framework, y emite errores si:
- un módulo sin
vendor:true
depende de un módulo convendor:true
o - un módulo con
vendor:true
depende de un módulo que no esllndk_library
y que no tienevendor:true
nivendor_available:true
.
La verificación de dependencias se aplica a header_libs
,
static_libs
y shared_libs
en
Android.bp
y, para LOCAL_HEADER_LIBRARIES
,
LOCAL_STATIC_LIBRARIES
y LOCAL_SHARED_LIBRARIES
en
Android.mk
LL-NDK
Las bibliotecas compartidas de LL-NDK son bibliotecas compartidas con ABI estables. Ambos framework
y proveedores comparten la misma implementación, la más reciente. Por cada
En la biblioteca compartida de LL-NDK, cc_library
contiene un
Propiedad llndk
con un archivo de símbolos:
cc_library { name: "libvndksupport", llndk: { symbol_file: "libvndksupport.map.txt", }, }
El archivo de símbolos describe los símbolos visibles para los módulos de los proveedores. Por ejemplo:
LIBVNDKSUPPORT { global: android_load_sphal_library; # llndk android_unload_sphal_library; # llndk local: *; };
Según el archivo de símbolos, el sistema de compilación genera una biblioteca compartida de stub para
módulos de proveedores, que se vinculan con estas bibliotecas cuando
Se habilitó BOARD_VNDK_VERSION
. El código auxiliar incluye un símbolo
biblioteca compartida solo si:
- No está definido al final de la sección con
_PRIVATE
o_PLATFORM
, - No tiene la etiqueta
#platform-only
. - No tiene etiquetas
#introduce*
o la etiqueta coincide con el objetivo.
VNDK
En los archivos Android.bp
, cc_library
,
cc_library_static
, cc_library_shared
y
Las definiciones del módulo cc_library_headers
admiten tres tipos
propiedades: vendor_available
, vndk.enabled
y
vndk.support_system_process
Si vendor_available
o vndk.enabled
es
true
, hay dos variantes (núcleo y proveedor) que se
construyen. La variante principal se debe tratar como un módulo de framework y se debe tratar al proveedor
variante debe tratarse como un módulo de proveedor. Si algunos módulos del framework dependen
en este módulo, se compila la variante principal. Si algunos módulos de proveedores
depender de este módulo, se compila la variante del proveedor. El sistema de compilación aplica
la siguiente verificación de dependencias:
- La variante principal siempre es exclusiva del framework y es inaccesible para el proveedor. módulos.
- Los módulos del framework no siempre pueden acceder a la variante del proveedor.
- Todas las dependencias de la variante del proveedor, que se especifican en
header_libs
,static_libs
oshared_libs
, debe serllndk_library
o módulo convendor_available
ovndk.enabled
. - Si
vendor_available
estrue
, la variante del proveedor sea accesible para todos los módulos de proveedores. - Si
vendor_available
esfalse
, la variante del proveedor será accesible únicamente para otros módulos VNDK o VNDK-SP (es decir, módulos convendor:true
no puede vincularvendor_available:false
módulos).
La ruta de instalación predeterminada para cc_library
o
cc_library_shared
se determina según las siguientes reglas:
- La variante principal se instala en
/system/lib[64]
. - El proceso de instalación de la variante del proveedor puede variar:
- Si
vndk.enabled
esfalse
, la variante del proveedor está instalada en/vendor/lib[64]
. - Si
vndk.enabled
estrue
, la variante del proveedor esté instalado en VNDK APEX(com.android.vndk.v${VER}
).
- Si
En la siguiente tabla, se resume la forma en que el sistema de compilación maneja las variantes de los proveedores:
proveedor_disponible | vndk habilitado |
vndk support_same_process |
Descripciones de variantes del proveedor |
---|---|---|---|
true |
false |
false |
Las variantes de proveedores son SOLO VND. Las bibliotecas compartidas son
Se instaló en /vendor/lib[64] . |
true |
No válido (error de compilación) | ||
true |
false |
Las variantes de proveedores son VNDK. Se instalaron las bibliotecas compartidas a VNDK APEX. | |
true |
Las variantes de proveedores son VNDK-SP. Las bibliotecas compartidas son instalarse en VNDK APEX. | ||
|
|
|
No hay variantes de proveedores. Este módulo es SOLO PARA FWK. |
true |
No válido (error de compilación) | ||
true |
false |
Las variantes de proveedores son VNDK-Private. Las bibliotecas compartidas son instalarse en VNDK APEX. Estas no deben ser que los módulos de los proveedores usan directamente. | |
true |
Las variantes de proveedores son VNDK-SP-Private. Las bibliotecas compartidas son instalarse en VNDK APEX. Estas no deben ser que los módulos de los proveedores usan directamente. |
Extensiones del VNDK
Las extensiones del VNDK son bibliotecas compartidas del VNDK con APIs adicionales. Las extensiones son
instalada en /vendor/lib[64]/vndk[-sp]
(sin sufijo de versión)
y anular las bibliotecas compartidas del VNDK original en el tiempo de ejecución.
Cómo definir las extensiones del VNDK
En Android 9 y versiones posteriores, Android.bp
es compatible de forma nativa con VNDK.
extensiones. Para compilar una extensión de VNDK, define otro módulo con una
vendor:true
y una propiedad extends
:
cc_library { name: "libvndk", vendor_available: true, vndk: { enabled: true, }, } cc_library { name: "libvndk_ext", vendor: true, vndk: { enabled: true, extends: "libvndk", }, }
Un módulo con vendor:true
, vndk.enabled:true
y
Las propiedades de extends
definen la extensión de VNDK:
- La propiedad
extends
debe especificar una biblioteca compartida de VNDK base nombre de la biblioteca (o el nombre de la biblioteca compartida VNDK-SP). - Las extensiones del VNDK (o extensiones VNDK-SP) llevan el nombre del módulo básico.
los nombres con los que se extienden. Por ejemplo, el objeto binario de salida de
libvndk_ext
eslibvndk.so
en lugar delibvndk_ext.so
- Las extensiones del VNDK se instalan en
/vendor/lib[64]/vndk
. - Las extensiones VNDK-SP se instalan en
/vendor/lib[64]/vndk-sp
- Las bibliotecas compartidas base deben tener
vndk.enabled:true
yvendor_available:true
.
Una extensión VNDK-SP debe extenderse desde una biblioteca compartida VNDK-SP
(vndk.support_system_process
debe ser igual):
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, }, }
Las extensiones del VNDK (o extensiones del VNDK-SP) pueden depender de las herramientas compartidas por otros proveedores. 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, }
Cómo usar extensiones del VNDK
Si un módulo de proveedor depende de APIs adicionales definidas por las extensiones del VNDK, el
debe especificar el nombre de la extensión VNDK en su
Propiedad 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", ], }
Si un módulo de proveedor depende de extensiones del VNDK, esas extensiones se
Se instalará en /vendor/lib[64]/vndk[-sp]
automáticamente. Si un módulo
ya no depende de una extensión VNDK, agrega un paso limpio a
CleanSpec.mk
para quitar la biblioteca compartida. Por ejemplo:
$(call add-clean-step, rm -rf $(TARGET_OUT_VENDOR)/lib/libvndk.so)
Compilación condicional
En esta sección, se describe cómo abordar las diferencias sutiles (p.ej., agregar o quitar una función de una de las variantes) entre las siguientes tres bibliotecas compartidas VNDK:
- Variante principal (p.ej.,
/system/lib[64]/libexample.so
) - Variante del proveedor (p.ej.,
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so
) - Extensión VNDK (p.ej.,
/vendor/lib[64]/vndk[-sp]/libexample.so
)
Marcas condicionales del compilador
El sistema de compilación de Android define __ANDROID_VNDK__
para el proveedor.
variantes y extensiones del VNDK de forma predeterminada. Puedes proteger el código
con las protecciones del preprocesador de C:
void all() { } #if !defined(__ANDROID_VNDK__) void framework_only() { } #endif #if defined(__ANDROID_VNDK__) void vndk_only() { } #endif
Además de __ANDROID_VNDK__
, diferentes cflags
o
Se puede especificar cppflags
en Android.bp
. El
cflags
o cppflags
especificados en
target.vendor
es específico de la variante del proveedor.
Por ejemplo, el siguiente Android.bp
define
libexample
y 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 es la lista de código 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
Según estos dos archivos, el sistema de compilación genera bibliotecas compartidas. con los siguientes símbolos exportados:
Ruta de instalación | 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 y vndk_ext |
Requisitos para los símbolos exportados
El verificador de ABI del VNDK
compara la ABI de las variantes de los proveedores del VNDK y
Extensiones del VNDK a los volcados de ABI de referencia en
prebuilts/abi-dumps/vndk
- Símbolos exportados por variantes de proveedores del VNDK (p.ej.,
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so
) deben ser idénticos a los símbolos definidos en los volcados de ABI (no a los superconjuntos de estos). - Símbolos exportados por extensiones de VNDK (p.ej.,
/vendor/lib[64]/vndk/libexample.so
) deben ser superconjuntos de la definidos en los volcados de ABI.
Si no se cumplen las variantes de los proveedores del VNDK ni las extensiones del VNDK de acuerdo con los requisitos anteriores, el verificador de ABI del VNDK emite errores de compilación y detiene la compilar.
Cómo excluir archivos de origen o bibliotecas compartidas de variantes de proveedores
Para excluir archivos fuente de la variante del proveedor, agrégalos al
exclude_srcs
. Del mismo modo, para garantizar que las bibliotecas compartidas
no está vinculada con la variante del proveedor, agrega esas bibliotecas a la
exclude_shared_libs
. Por ejemplo:
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"], }, }, }
En este ejemplo, se muestra la variante principal de libexample_cond_exclude
incluye el código de fwk.c
y both.c
, y depende
en las bibliotecas compartidas libfwk_only
y libboth
. El
variante de proveedor de libexample_cond_exclude
incluye solo el código
de both.c
porque fwk.c
es excluido por
exclude_srcs
. Del mismo modo, solo depende de la biblioteca compartida
libboth
porque libfwk_only
es excluido por el
propiedad exclude_shared_libs
.
Cómo exportar encabezados de extensiones de VNDK
Una extensión del VNDK puede agregar clases o funciones nuevas a un VNDK compartido. biblioteca. Se recomienda mantener esas declaraciones en encabezados independientes y evita cambiar los encabezados existentes.
Por ejemplo, un archivo de encabezado nuevo
Se crea include-ext/example/ext/feature_name.h
para el VNDK
extensión libexample_ext
:
- Android.bp
- include-ext/example/ext/nombre_de_función.h
- include/example/example.h
- src/ejemplo.c
- src/ext/feature_name.c
En el siguiente Android.bp
, libexample
exportaciones
solo include
, mientras que libexample_ext
exporta ambas
include
y include-ext
. Esto garantiza
feature_name.h
no se incluirán incorrectamente en los usuarios 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", }, }
Si no es posible separar las extensiones con archivos de encabezado independientes, un
como alternativa, puedes agregar protecciones #ifdef
. Sin embargo, asegúrate de que todos
Los usuarios de la extensión VNDK agregan las marcas de definición. Puedes definir
cc_defaults
para agregar marcas de definición a cflags
y vincular
bibliotecas compartidas con shared_libs
.
Por ejemplo, para agregar una nueva función de miembro Example2::get_b()
a
la extensión libexample2_ext
del VNDK, debes modificar el archivo
de encabezado y agrega una protección #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_
Un cc_defaults
llamado libexample2_ext_defaults
es
definido para los usuarios 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", ], }
Los usuarios de libexample2_ext
pueden simplemente incluir
libexample2_ext_defaults
en su defaults
propiedad:
cc_binary { name: "example2_user_executable", defaults: ["libexample2_ext_defaults"], vendor: true, }
Paquetes de productos
En el sistema de compilación de Android, la variable PRODUCT_PACKAGES
especifica los ejecutables, las bibliotecas compartidas o los paquetes que se deben
instalada en el dispositivo. Las dependencias transitivas del tipo
módulos también se instalan implícitamente en el dispositivo.
Si habilitas BOARD_VNDK_VERSION
, los módulos con
vendor_available
o vndk.enabled
son especiales
tratamiento. Si un módulo de framework depende de un módulo con
vendor_available
o vndk.enabled
, que son la variante principal
se incluye en el conjunto de instalación transitivo. Si un módulo de proveedor
depende de un módulo con vendor_available
, la variante de proveedor es
incluido en el conjunto de instalación transitivo. Sin embargo, las variantes de módulos de proveedores
con vndk.enabled
se instalan sin importar si los usan o no los módulos de proveedores.
Cuando las dependencias son invisibles para el sistema de compilación (p.ej., bibliotecas compartidas)
que se puede abrir con dlopen()
en el tiempo de ejecución), debes especificar
los nombres de los módulos en PRODUCT_PACKAGES
para instalar esos módulos
de forma explícita.
Si un módulo tiene vendor_available
o vndk.enabled
,
el nombre del módulo significa su variante principal. Para especificar explícitamente el
variante de proveedor en PRODUCT_PACKAGES
, agrega un .vendor
en el nombre del módulo. Por ejemplo:
cc_library { name: "libexample", srcs: ["example.c"], vendor_available: true, }
En este ejemplo, libexample
significa
/system/lib[64]/libexample.so
y libexample.vendor
significa /vendor/lib[64]/libexample.so
. Para instalar
/vendor/lib[64]/libexample.so
, agregar libexample.vendor
a PRODUCT_PACKAGES
:
PRODUCT_PACKAGES += libexample.vendor