VNDK-Build-Systemunterstützung

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:

libexamplevendor_available:true und vndk.enabled:true

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 ist true.

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}

VNDK APEX

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 mit vendor:true oder
  • hängt ein Modul mit vendor:true von einem Nicht-llndk_library-Modul, das weder vendor:true oder vendor_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.
<ph type="x-smartling-placeholder">

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/oder shared_libs, muss entweder eine llndk_library- oder eine mit vendor_available oder vndk.enabled.
  • Wenn vendor_available den Wert true hat, ist die Anbietervariante ist für alle Anbietermodule zugänglich.
  • Wenn vendor_available den Wert false hat, ist die Anbietervariante nur für andere VNDK- oder VNDK-SP-Module (d.h. Module mit vendor:true kann vendor_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 Wert false hat, ist die Anbietervariante ist in /vendor/lib[64] installiert.
    • Wenn vndk.enabled den Wert true hat, ist die Anbietervariante in VNDK APEX(com.android.vndk.v${VER}) installiert.

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.

false

false

false

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.
<ph type="x-smartling-placeholder">

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 ist libvndk.so statt libvndk_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 und vendor_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 dem 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 an den Modulnamen an. 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