Unter Android 8.1 und höher verfügt das Build-System über integrierte VNDK-Unterstützung. Wann? VNDK-Unterstützung aktiviert ist, prüft das Build-System die Abhängigkeiten zwischen Module, erstellt eine anbieterspezifische Variante für Anbietermodule und Diese Module werden automatisch in dafür vorgesehenen Verzeichnissen installiert.
Beispiel für VNDK-Build-Support
In diesem Beispiel definiert die Moduldefinition Android.bp
mit dem Namen libexample
. Das vendor_available
gibt an, dass Framework-Module und Anbietermodule von
libexample
:
Abbildung 1: Unterstützung aktiviert.
Sowohl die ausführbare Framework /system/bin/foo
als auch der Anbieter
die ausführbare Datei /vendor/bin/bar
von libexample
und
haben libexample
in ihren shared_libs
-Properties.
Wenn libexample
sowohl von Framework-Modulen als auch vom Anbieter verwendet wird
werden zwei Varianten von libexample
erstellt. Die Hauptvariante
(nach libexample
benannt) wird von Framework-Modulen und dem
Die Anbietervariante (nach libexample.vendor
benannt) wird vom Anbieter verwendet.
Module. Die beiden Varianten werden in verschiedenen Verzeichnissen installiert:
- Die Hauptvariante wird in
/system/lib[64]/libexample.so
- Die Anbietervariante wurde in VNDK APEX installiert, weil
vndk.enabled
isttrue
.
Weitere Informationen finden Sie unter Moduldefinition.
Build-Unterstützung konfigurieren
Um die vollständige Unterstützung des Build-Systems für ein Produktgerät zu aktivieren, fügen Sie
BOARD_VNDK_VERSION
in BoardConfig.mk
:
BOARD_VNDK_VERSION := current
Diese Einstellung hat einen globalen Effekt: Wenn definiert in
BoardConfig.mk
, alle Module sind geprüft. Da es keinen Mechanismus gibt,
eines problematischen Moduls auf die Sperr- oder Zulassungsliste setzen,
unnötige Abhängigkeiten, bevor Sie BOARD_VNDK_VERSION
hinzufügen. Ich
kann ein Modul testen und kompilieren, indem BOARD_VNDK_VERSION
in
Ihre Umgebungsvariablen:
$ BOARD_VNDK_VERSION=current m module_name.vendor
Wenn BOARD_VNDK_VERSION
aktiviert ist, werden mehrere globale
Header-Suchpfade werden entfernt. Dazu gehören:
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
Wenn ein Modul von den Headern aus diesen Verzeichnissen abhängig ist, müssen Sie
die Abhängigkeiten (explizit) mit header_libs
,
static_libs
und/oder shared_libs
.
VNDK APEX
Unter Android 10 und niedriger wurden Module mit vndk.enabled
installiert in
/system/lib[64]/vndk[-sp]-${VER}
. Unter Android 11 und höher
VNDK-Bibliotheken sind in einem APEX-Format gepackt und der Name von VNDK APEX lautet
com.android.vndk.v${VER}
Je nach Gerätekonfiguration
VNDK APEX ist abgeflachte oder nicht vereinfachte und ist über den kanonischen Pfad verfügbar.
/apex/com.android.vndk.v${VER}
Abbildung 2: VNDK APEX
Moduldefinition
Wenn du Android mit BOARD_VNDK_VERSION
entwickeln möchtest, musst du die
Moduldefinition entweder in Android.mk
oder
Android.bp
In diesem Abschnitt werden verschiedene Arten von Modulen beschrieben,
Definitionen, verschiedene VNDK-bezogene Moduleigenschaften und Abhängigkeitsprüfungen
die im Build-System implementiert sind.
Anbietermodule
Anbietermodule sind anbieterspezifische ausführbare Dateien oder gemeinsam genutzte Bibliotheken, die
muss in einer Anbieterpartition installiert werden. In Android.bp
Dateien,
Die Anbietermodule müssen die Anbieter- oder proprietäre Eigenschaft auf true
setzen.
In Android.mk
-Dateien müssen Anbietermodule festgelegt werden
LOCAL_VENDOR_MODULE
oder LOCAL_PROPRIETARY_MODULE
bis
true
.
Wenn BOARD_VNDK_VERSION
definiert ist, lässt das Build-System dies nicht zu.
zwischen Anbieter- und Framework-Modulen und gibt in folgenden Fällen Fehler aus:
- Ein Modul ohne
vendor:true
hängt von einem Modul mitvendor:true
oder - hängt ein Modul mit
vendor:true
von einem Nicht-llndk_library
-Modul, das wedervendor:true
odervendor_available:true
.
Die Abhängigkeitsprüfung gilt für header_libs
,
static_libs
und shared_libs
in
Android.bp
und an LOCAL_HEADER_LIBRARIES
,
LOCAL_STATIC_LIBRARIES
und LOCAL_SHARED_LIBRARIES
in
Android.mk
LL-NDK
Gemeinsam genutzte LL-NDK-Bibliotheken mit stabilen ABIs. Beide Frameworks
und die Anbietermodule die gleiche und die neueste Implementierung verwenden. Für jede
LL-NDK gemeinsam genutzt, enthält die cc_library
ein
llndk
-Eigenschaft mit einer Symboldatei:
cc_library { name: "libvndksupport", llndk: { symbol_file: "libvndksupport.map.txt", }, }
Die Symboldatei beschreibt die für Anbietermodule sichtbaren Symbole. Beispiel:
LIBVNDKSUPPORT { global: android_load_sphal_library; # llndk android_unload_sphal_library; # llndk local: *; };
Basierend auf der Symboldatei generiert das Build-System eine gemeinsam genutzte Stub-Bibliothek für
Anbietermodule, die mit diesen Bibliotheken verknüpft sind,
BOARD_VNDK_VERSION
ist aktiviert. Der Stub enthält ein Symbol.
der gemeinsam genutzten Bibliothek, wenn Folgendes zutrifft:
- Ist nicht am Ende des Abschnitts mit
_PRIVATE
definiert oder_PLATFORM
, - Enthält kein
#platform-only
-Tag und - Hat keine
#introduce*
-Tags oder das Tag stimmt mit dem Ziel.
VNDK (VNDK)
In Android.bp
Dateien, cc_library
,
cc_library_static
, cc_library_shared
und
Die Moduldefinitionen „cc_library_headers
“ unterstützen drei VNDK-bezogene
Properties: vendor_available
, vndk.enabled
und
vndk.support_system_process
Wenn vendor_available
oder vndk.enabled
gleich
true
können zwei Varianten (Hauptprodukt und Anbieter)
entwickelt. Die Kernvariante sollte als Framework-Modul und als Anbieter
sollte als Anbietermodul behandelt werden. Wenn einige Framework-Module
In diesem Modul wurde
die Kernvariante entwickelt. Wenn einige Anbietermodule
von diesem Modul abhängen, wird die Anbietervariante erstellt. Das Build-System erzwingt
die folgenden Abhängigkeitsprüfungen ausführen:
- Die Kernvariante ist immer nur Framework und für den Anbieter nicht zugänglich Module.
- Auf die Anbietervariante kann immer nicht auf Framework-Module zugegriffen werden.
- Alle Abhängigkeiten der Anbietervariante, die in
header_libs
,static_libs
und/odershared_libs
, muss entweder einellndk_library
- oder eine mitvendor_available
odervndk.enabled
. - Wenn
vendor_available
den Werttrue
hat, ist die Anbietervariante ist für alle Anbietermodule zugänglich. - Wenn
vendor_available
den Wertfalse
hat, ist die Anbietervariante nur für andere VNDK- oder VNDK-SP-Module (d.h. Module mitvendor:true
kannvendor_available:false
nicht verknüpfen Module).
Der Standardinstallationspfad für cc_library
oder
cc_library_shared
wird durch die folgenden Regeln bestimmt:
- Die Hauptvariante wird in
/system/lib[64]
installiert. - Der Installationspfad der Anbietervariante kann variieren:
<ph type="x-smartling-placeholder">
- </ph>
- Wenn
vndk.enabled
den Wertfalse
hat, ist die Anbietervariante ist in/vendor/lib[64]
installiert. - Wenn
vndk.enabled
den Werttrue
hat, ist die Anbietervariante in VNDK APEX(com.android.vndk.v${VER}
) installiert.
- Wenn
In der folgenden Tabelle ist zusammengefasst, wie das Build-System die Anbietervarianten verarbeitet:
Anbieter_verfügbar | vndk aktiviert |
vndk support_same_process |
Beschreibungen der Anbietervarianten |
---|---|---|---|
true |
false |
false |
Die Anbietervarianten sind NUR VND-konform. Gemeinsam genutzte Bibliotheken sind
in /vendor/lib[64] installiert. |
true |
Ungültig (Build-Fehler) | ||
true |
false |
Die Anbietervarianten sind VNDK. Gemeinsam genutzte Bibliotheken sind installiert an VNDK APEX. | |
true |
Die Anbietervarianten sind VNDK-SP. Gemeinsam genutzte Bibliotheken sind VNDK APEX installiert ist. | ||
|
|
|
Keine Anbietervarianten. Dieses Modul ist NUR FWK-spezifisch. |
true |
Ungültig (Build-Fehler) | ||
true |
false |
Die Anbietervarianten sind VNDK-Private. Gemeinsam genutzte Bibliotheken sind VNDK APEX installiert ist. Diese Adressen dürfen nicht direkt von Anbietermodulen verwendet werden. | |
true |
Die Anbietervarianten sind VNDK-SP-Private. Gemeinsam genutzte Bibliotheken sind VNDK APEX installiert ist. Diese Adressen dürfen nicht direkt von Anbietermodulen verwendet werden. |
VNDK-Erweiterungen
VNDK-Erweiterungen sind gemeinsam genutzte VNDK-Bibliotheken mit zusätzlichen APIs. Erweiterungen sind
installiert in /vendor/lib[64]/vndk[-sp]
(ohne Versionssuffix)
und die ursprünglichen gemeinsam genutzten
VNDK-Bibliotheken während der Laufzeit überschreiben.
VNDK-Erweiterungen definieren
Ab Android 9 unterstützt Android.bp
VNDK nativ
Erweiterungen. Definieren Sie zum Erstellen einer VNDK-Erweiterung ein weiteres Modul mit einem
vendor:true
und eine extends
-Property:
cc_library { name: "libvndk", vendor_available: true, vndk: { enabled: true, }, } cc_library { name: "libvndk_ext", vendor: true, vndk: { enabled: true, extends: "libvndk", }, }
Ein Modul mit vendor:true
, vndk.enabled:true
und
Mit extends
-Eigenschaften wird die VNDK-Erweiterung definiert:
- Im Attribut
extends
muss eine gemeinsam genutzte Basisbibliothek gemäß VNDK angegeben werden (oder den Namen der gemeinsam genutzten Bibliothek gemäß VNDK-SP). - VNDK- oder VNDK-SP-Erweiterungen sind nach dem Basismodul benannt
aus denen sie stammen. Die Ausgabebinärdatei von
libvndk_ext
istlibvndk.so
stattlibvndk_ext.so
- VNDK-Erweiterungen sind in
/vendor/lib[64]/vndk
installiert. - VNDK-SP-Erweiterungen werden installiert in
/vendor/lib[64]/vndk-sp
- Die gemeinsam genutzte Basisbibliothek muss
vndk.enabled:true
haben undvendor_available:true
.
Eine VNDK-SP-Erweiterung muss aus einer gemeinsam genutzten Bibliothek gemäß VNDK-SP stammen
(vndk.support_system_process
muss gleich sein):
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, }, }
VNDK- oder VNDK-SP-Erweiterungen können von anderen Anbietern abhängig sein Bibliotheken:
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, }<ph type="x-smartling-placeholder">
VNDK-Erweiterungen verwenden
Wenn ein Anbietermodul von zusätzlichen APIs abhängig ist, die durch VNDK-Erweiterungen definiert sind,
muss den Namen der VNDK-Erweiterung in seiner
shared_libs
-Property:
// 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", ], }
Wenn ein Anbietermodul von VNDK-Erweiterungen abhängt, sind diese VNDK-Erweiterungen
automatisch in /vendor/lib[64]/vndk[-sp]
installiert. Wenn ein Modul
nicht mehr von einer VNDK-Erweiterung abhängt, fügen Sie
CleanSpec.mk
, um die gemeinsam genutzte Bibliothek zu entfernen. Beispiel:
$(call add-clean-step, rm -rf $(TARGET_OUT_VENDOR)/lib/libvndk.so)
Bedingte Kompilierung
In diesem Abschnitt wird beschrieben, wie Sie mit den kleinen Unterschieden (z.B. Hinzufügen oder Entfernen eines Elements aus einer der Varianten) zwischen den folgenden drei gemeinsam genutzte VNDK-Bibliotheken:
- Hauptvariante (z.B.
/system/lib[64]/libexample.so
) - Anbietervariante (z.B.
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so
) - VNDK-Erweiterung (z.B.
/vendor/lib[64]/vndk[-sp]/libexample.so
)
Bedingte Compiler-Flags
Das Android-Build-System definiert __ANDROID_VNDK__
für den Anbieter
und VNDK-Erweiterungen standardmäßig enthalten. Du darfst den Code schützen
mit den C-Präprozessor-Guards:
void all() { } #if !defined(__ANDROID_VNDK__) void framework_only() { } #endif #if defined(__ANDROID_VNDK__) void vndk_only() { } #endif
Neben __ANDROID_VNDK__
können abweichende Werte für cflags
oder
cppflags
kann in Android.bp
angegeben werden. Die
cflags
oder cppflags
angegeben in
target.vendor
ist spezifisch für die Anbietervariante.
Beispielsweise definiert die folgende Android.bp
libexample
und 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", ], }
Und so sieht die Codeauflistung von src/example.c
aus:
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
Gemäß diesen beiden Dateien generiert das Build-System gemeinsam genutzte Bibliotheken. mit den folgenden exportierten Symbolen:
Installationspfad | Exportierte Symbole |
---|---|
/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 |
Anforderungen an exportierte Symbole
Die VNDK ABI-Prüfung
vergleicht die ABI von VNDK-Anbietervarianten und
VNDK-Erweiterungen zu den Referenz-ABI-Dumps unter
prebuilts/abi-dumps/vndk
- Symbole, die von VNDK-Anbietervarianten exportiert wurden (z.B.
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so
) muss identisch sein an (nicht die Obermengen der) der in ABI-Dumps definierten Symbole. - Aus VNDK-Erweiterungen exportierte Symbole (z.B.
/vendor/lib[64]/vndk/libexample.so
) müssen Obermengen von die in den ABI-Dumps definiert sind.
Wenn VNDK-Anbietervarianten oder VNDK-Erweiterungen nicht befolgt werden die oben genannten Anforderungen erfüllt, gibt die VNDK ABI-Prüfung Build-Fehler aus und stoppt erstellen.
Quelldateien oder freigegebene Bibliotheken von Anbietervarianten ausschließen
Um Quelldateien aus der Anbietervariante auszuschließen, fügen Sie sie zum
exclude_srcs
-Property. Um sicherzustellen, dass gemeinsam genutzte Bibliotheken
nicht mit der Anbietervariante verknüpft sind, fügen Sie diese Bibliotheken
exclude_shared_libs
-Property. Beispiel:
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"], }, }, }
In diesem Beispiel ist die Kernvariante von libexample_cond_exclude
enthält den Code aus fwk.c
und both.c
und hängt
in den gemeinsam genutzten Bibliotheken libfwk_only
und libboth
. Die
Die Anbietervariante von libexample_cond_exclude
enthält nur den Code
aus both.c
, da fwk.c
durch den
exclude_srcs
. Ebenso ist nur die gemeinsam genutzte Bibliothek abhängig,
libboth
, weil libfwk_only
durch den
exclude_shared_libs
-Property.
Header aus VNDK-Erweiterungen exportieren
Mit einer VNDK-Erweiterung können einer VNDK-Freigabe neue Klassen oder neue Funktionen hinzugefügt werden Bibliothek. Es wird empfohlen, diese Deklarationen in separaten Überschriften zu verwenden. und vermeiden Sie es, die vorhandenen Header zu ändern.
Beispielsweise kann eine neue Headerdatei
include-ext/example/ext/feature_name.h
wird für den VNDK erstellt
Erweiterung libexample_ext
:
- Android.bp
- include-ext/beispiel/ext/feature_name.h
- include/beispiel/beispiel.h
- src/beispiel.c
- src/ext/feature_name.c
Im folgenden Android.bp
wurde libexample
exportiert
nur include
, während libexample_ext
beide exportiert
include
und include-ext
. Dadurch wird sichergestellt,
feature_name.h
wird von den Nutzern von nicht fälschlicherweise eingeschlossen
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", }, }
Wenn die Trennung von Erweiterungen durch unabhängige Headerdateien nicht möglich ist, wird ein
Alternativ können Sie #ifdef
Guards hinzufügen. Achten Sie jedoch darauf, dass alle
Nutzer der VNDK-Erweiterung fügen die Definition-Flags hinzu. Sie können
cc_defaults
, um cflags
Definieren-Flags hinzuzufügen und zu verknüpfen
hat Fotogalerien mit shared_libs
geteilt.
Um z. B. eine neue Mitgliedsfunktion Example2::get_b()
der VNDK-Erweiterung libexample2_ext
muss, müssen Sie die vorhandene
Headerdatei und fügen Sie einen #ifdef
-Guard hinzu:
#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_
Eine cc_defaults
mit dem Namen libexample2_ext_defaults
ist
definiert für Nutzer von 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", ], }
Die Nutzer von libexample2_ext
könnten einfach Folgendes einschließen:
libexample2_ext_defaults
in defaults
Property:
cc_binary { name: "example2_user_executable", defaults: ["libexample2_ext_defaults"], vendor: true, }
Produktpakete
Im Android-Build-System wird die Variable PRODUCT_PACKAGES
gibt die ausführbaren Dateien, gemeinsam genutzten Bibliotheken oder Pakete an, die
auf dem Gerät installiert ist. Die transitiven Abhängigkeiten der angegebenen
Module ebenfalls implizit auf dem Gerät installiert sind.
Wenn BOARD_VNDK_VERSION
aktiviert ist, werden Module mit
Besondere Angebote für vendor_available
oder vndk.enabled
Behandlung. Ob ein Framework-Modul von einem Modul mit
vendor_available
oder vndk.enabled
, die Hauptvariante
ist im transitiven Installationssatz enthalten. Wenn ein Anbietermodul
von einem Modul mit vendor_available
abhängt, ist die Anbietervariante
im transitiven Installationssatz enthalten. Anbietervarianten von Modulen
mit vndk.enabled
installiert werden, unabhängig davon, ob sie von Anbietermodulen verwendet werden oder nicht.
Wenn die Abhängigkeiten für das Build-System nicht sichtbar sind (z.B. gemeinsam genutzte Bibliotheken)
das in der Laufzeit mit dlopen()
geöffnet werden kann), sollten Sie
die Modulnamen in PRODUCT_PACKAGES
, um diese Module zu installieren
explizit auf.
Wenn ein Modul vendor_available
oder vndk.enabled
hat,
der Modulname für die
Kernvariante steht. Um den Parameter
Anbietervariante in PRODUCT_PACKAGES
, hängen Sie eine .vendor
an
zum Modulnamen hinzu. Beispiel:
cc_library { name: "libexample", srcs: ["example.c"], vendor_available: true, }
In diesem Beispiel steht libexample
für
/system/lib[64]/libexample.so
und libexample.vendor
steht für /vendor/lib[64]/libexample.so
. Installation
/vendor/lib[64]/libexample.so
, libexample.vendor
hinzufügen
an PRODUCT_PACKAGES
:
PRODUCT_PACKAGES += libexample.vendor