VNDK-Build-Systemunterstützung

Mit Sammlungen den Überblick behalten Sie können Inhalte basierend auf Ihren Einstellungen speichern und kategorisieren.

In Android 8.1 und höher verfügt das Build-System über eine integrierte VNDK-Unterstützung. Wenn die VNDK-Unterstützung aktiviert ist, überprüft das Build-System die Abhängigkeiten zwischen Modulen, erstellt eine anbieterspezifische Variante für Anbietermodule und installiert diese Module automatisch in festgelegten Verzeichnissen.

Beispiel für die Unterstützung von VNDK-Builds

In diesem Beispiel definiert die Android.bp eine Bibliothek namens libexample . Die Eigenschaft vendor_available gibt Framework-Module an und Herstellermodule können von libexample abhängen:

libexample supplier_available:true und vndk.enabled:true

Abbildung 1. VNDK-Unterstützung aktiviert

Sowohl die ausführbare Framework-Datei /system/bin/foo als auch die ausführbare Datei des Anbieters /vendor/bin/bar hängen von libexample und haben libexample in ihren shared_libs Eigenschaften.

Wenn libexample sowohl von Framework-Modulen als auch von Herstellermodulen verwendet wird, werden zwei Varianten von libexample . Die Core-Variante (benannt nach libexample ) wird von Framework-Modulen verwendet und die Vendor-Variante (benannt nach libexample.vendor ) wird von Vendor-Modulen verwendet. Die beiden Varianten werden in unterschiedliche Verzeichnisse installiert:

  • Die Core-Variante wird in /system/lib[64]/libexample.so installiert.
  • Die Herstellervariante wird in VNDK APEX installiert, weil vndk.enabled true ist.

Weitere Einzelheiten finden Sie unter Moduldefinition .

Build-Unterstützung konfigurieren

Um die vollständige Build-Systemunterstützung für ein Produktgerät zu aktivieren, fügen BOARD_VNDK_VERSION zu BoardConfig.mk hinzu:

BOARD_VNDK_VERSION := current

Diese Einstellung wirkt sich global aus: Wenn in BoardConfig.mk definiert, werden alle Module geprüft. Da es keinen Mechanismus gibt, um ein störendes Modul auf die schwarze oder weiße Liste zu setzen, sollten Sie alle unnötigen Abhängigkeiten bereinigen, bevor BOARD_VNDK_VERSION hinzufügen. Sie können ein Modul testen und kompilieren, indem BOARD_VNDK_VERSION in Ihren Umgebungsvariablen festlegen:

$ BOARD_VNDK_VERSION=current m module_name.vendor

Wenn BOARD_VNDK_VERSION aktiviert ist, werden mehrere standardmäßige globale Header-Suchpfade entfernt . Diese beinhalten:

  • 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ängt, müssen Sie die Abhängigkeiten (explizit) mit header_libs , static_libs und/oder shared_libs .

VNDK-APEX

In Android 10 und niedriger wurden Module mit vndk.enabled in /system/lib[64]/vndk[-sp]-${VER} installiert. In Android 11 und höher sind VNDK-Bibliotheken in einem APEX-Format verpackt und der Name von VNDK APEX lautet com.android.vndk.v${VER} . Je nach Gerätekonfiguration ist VNDK APEX abgeflacht oder nicht abgeflacht und über den kanonischen Pfad /apex/com.android.vndk.v${VER} verfügbar.

VNDK-APEX

Abbildung 2. VNDK-APEX

Moduldefinition

Um Android mit BOARD_VNDK_VERSION zu erstellen, müssen Sie die Moduldefinition entweder in Android.mk oder Android.bp . In diesem Abschnitt werden verschiedene Arten von Moduldefinitionen, mehrere VNDK-bezogene Moduleigenschaften und im Buildsystem implementierte Abhängigkeitsprüfungen beschrieben.

Anbietermodule

Herstellermodule sind herstellerspezifische ausführbare Dateien oder gemeinsam genutzte Bibliotheken, die in einer Herstellerpartition installiert werden müssen. In Android.bp Dateien müssen Anbietermodule die Anbieter- oder proprietäre Eigenschaft auf true setzen. In Android.mk Dateien müssen Herstellermodule LOCAL_VENDOR_MODULE oder LOCAL_PROPRIETARY_MODULE auf true setzen.

Wenn BOARD_VNDK_VERSION definiert ist, verbietet das Build-System Abhängigkeiten zwischen Anbietermodulen und Framework-Modulen und gibt Fehler aus, wenn:

  • ein Modul ohne vendor:true hängt von einem Modul mit vendor:true ab, oder
  • Ein Modul mit dem Wert „ vendor:true “ hängt von einem Nicht llndk_library -Modul ab, das weder „ vendor:true “ noch vendor_available:true hat.

Die Abhängigkeitsprüfung gilt für header_libs , static_libs und shared_libs in Android.bp und für LOCAL_HEADER_LIBRARIES , LOCAL_STATIC_LIBRARIES und LOCAL_SHARED_LIBRARIES in Android.mk .

LL-NDK

LL-NDK Shared Libraries sind gemeinsam genutzte Bibliotheken mit stabilen ABIs. Sowohl Framework- als auch Herstellermodule haben dieselbe und die neueste Implementierung. Für jede gemeinsam genutzte LL-NDK-Bibliothek enthält Android.bp eine llndk_library -Moduldefinition:

llndk_library {
    name: "libvndksupport",
    symbol_file: "libvndksupport.map.txt",
}

Diese Moduldefinition gibt einen Modulnamen und eine Symboldatei an, die die Symbole beschreibt, die für Herstellermodule sichtbar sind. Zum 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 Herstellermodule, die mit diesen Bibliotheken verknüpft werden, wenn BOARD_VNDK_VERSION aktiviert ist. Ein Symbol wird nur dann in die gemeinsam genutzte Stub-Bibliothek aufgenommen, wenn es:

  • nicht im Abschnittsende mit _PRIVATE oder _PLATFORM ist,
  • Hat kein #platform-only Tag und
  • Hat keine #introduce* -Tags oder der Tag stimmt mit dem Ziel überein.

VNDK

In Android.bp Dateien unterstützen cc_library , cc_library_static , cc_library_shared und cc_library_headers drei VNDK-bezogene Eigenschaften: vendor_available , vndk.enabled und vndk.support_system_process .

Wenn vendor_available oder vndk.enabled auf " true " gesetzt ist, können zwei Varianten ( Core und Vendor ) erstellt werden. Die Core-Variante sollte als Framework-Modul und die Vendor-Variante als Vendor-Modul behandelt werden. Wenn einige Framework-Module von diesem Modul abhängen, wird die Core-Variante erstellt. Wenn einige Anbietermodule von diesem Modul abhängen, wird die Anbietervariante erstellt. Das Build-System erzwingt die folgenden Abhängigkeitsprüfungen:

  • Die Core-Variante ist immer Framework-only und für Herstellermodule nicht zugänglich.
  • Die Herstellervariante ist für Framework-Module immer unzugänglich.
  • Alle Abhängigkeiten der Herstellervariante, die in header_libs , static_libs und/oder shared_libs sind, müssen entweder eine llndk_library oder ein Modul mit vendor_available oder vndk.enabled .
  • Wenn der vendor_available true ist, ist die Anbietervariante für alle Anbietermodule zugänglich.
  • Wenn vendor_available false ist, ist die Anbietervariante nur für andere VNDK- oder VNDK-SP-Module zugänglich (dh Module mit „ vendor:true “ können nicht vendor_available:false -Module verknüpfen).

Der Standardinstallationspfad für cc_library oder cc_library_shared wird durch die folgenden Regeln bestimmt:

  • Die Core-Variante wird nach /system/lib[64] installiert.
  • Der Installationspfad der Anbietervariante kann variieren:
    • Wenn vndk.enabled false ist, wird die Herstellervariante in /vendor/lib[64] installiert.
    • Wenn vndk.enabled true ist, wird die Anbietervariante in VNDK APEX( com.android.vndk.v${VER} ) installiert.

Die folgende Tabelle fasst zusammen, wie das Build-System die Herstellervarianten handhabt:

Anbieter_verfügbar vndk
aktiviert
vndk
support_same_process
Beschreibungen der Anbietervarianten
true false false Die Anbietervarianten sind VND-ONLY . Gemeinsam genutzte Bibliotheken werden in /vendor/lib[64] installiert.
true Ungültig (Build-Fehler)
true false Die Anbietervarianten sind VNDK . Gemeinsam genutzte Bibliotheken werden in VNDK APEX installiert.
true Die Anbietervarianten sind VNDK-SP . Gemeinsam genutzte Bibliotheken werden in VNDK APEX installiert.

false

false

false

Keine Herstellervarianten. Dieses Modul ist NUR FWK .

true Ungültig (Build-Fehler)
true false Die Anbietervarianten sind VNDK-Private . Gemeinsam genutzte Bibliotheken werden in VNDK APEX installiert. Diese dürfen nicht direkt von Herstellermodulen verwendet werden.
true Die Anbietervarianten sind VNDK-SP-Private . Gemeinsam genutzte Bibliotheken werden in VNDK APEX installiert. Diese dürfen nicht direkt von Herstellermodulen verwendet werden.

VNDK-Erweiterungen

VNDK-Erweiterungen sind gemeinsam genutzte VNDK-Bibliotheken mit zusätzlichen APIs. Erweiterungen werden unter /vendor/lib[64]/vndk[-sp] (ohne Versionssuffix) installiert und überschreiben die ursprünglichen gemeinsam genutzten VNDK-Bibliotheken zur Laufzeit.

Definieren von VNDK-Erweiterungen

In Android 9 und höher unterstützt Android.bp nativ VNDK-Erweiterungen. Um eine VNDK-Erweiterung zu erstellen, definieren Sie ein weiteres Modul mit einer vendor:true extends und einer extend-Eigenschaft:

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 den Eigenschaften " vendor:true ", vndk.enabled:true und "Extended" definiert die extends -Erweiterung:

  • Die Eigenschaft „ extends “ muss einen Basisnamen der gemeinsam genutzten VNDK-Bibliothek (oder den Namen der gemeinsam genutzten VNDK-SP-Bibliothek) angeben.
  • VNDK-Erweiterungen (oder VNDK-SP-Erweiterungen) werden nach den Basismodulnamen benannt, von denen sie erweitert werden. Beispielsweise ist die Ausgabebinärdatei von libvndk_ext libvndk.so anstelle von libvndk_ext.so .
  • VNDK-Erweiterungen werden in /vendor/lib[64]/vndk .
  • VNDK-SP-Erweiterungen werden in /vendor/lib[64]/vndk-sp installiert.
  • Die gemeinsam genutzten Basisbibliotheken müssen sowohl vndk.enabled:true als vendor_available:true haben.

Eine VNDK-SP-Erweiterung muss von einer gemeinsam genutzten VNDK-SP-Bibliothek erweitert werden ( 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-Erweiterungen (oder VNDK-SP-Erweiterungen) können von gemeinsam genutzten Bibliotheken anderer Anbieter abhängen:

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,
}

Verwenden von VNDK-Erweiterungen

Wenn ein Anbietermodul von zusätzlichen APIs abhängt, die von VNDK-Erweiterungen definiert werden, muss das Modul den Namen der VNDK-Erweiterung in seiner Eigenschaft 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",
    ],
}

Wenn ein Herstellermodul von VNDK-Erweiterungen abhängt, werden diese VNDK-Erweiterungen automatisch unter /vendor/lib[64]/vndk[-sp] . Wenn ein Modul nicht mehr von einer VNDK-Erweiterung abhängt, fügen Sie CleanSpec.mk einen sauberen Schritt hinzu, um die gemeinsam genutzte Bibliothek zu entfernen. Zum Beispiel:

$(call add-clean-step, rm -rf $(TARGET_OUT_VENDOR)/lib/libvndk.so)

Bedingte Kompilierung

In diesem Abschnitt wird beschrieben, wie Sie mit den feinen Unterschieden (z. B. Hinzufügen oder Entfernen einer Funktion aus einer der Varianten) zwischen den folgenden drei gemeinsam genutzten VNDK-Bibliotheken umgehen:

  • Core-Variante (z. B. /system/lib[64]/libexample.so )
  • Herstellervariante (zB /apex/com.android.vndk.v${VER}/lib[64]/libexample.so )
  • VNDK-Erweiterung (zB /vendor/lib[64]/vndk[-sp]/libexample.so )

Bedingte Compiler-Flags

Das Android-Buildsystem definiert __ANDROID_VNDK__ für Herstellervarianten und VNDK-Erweiterungen. Sie können den Code mit den C-Präprozessorwächtern schützen:

void all() { }

#if !defined(__ANDROID_VNDK__)
void framework_only() { }
#endif

#if defined(__ANDROID_VNDK__)
void vndk_only() { }
#endif

Zusätzlich zu __ANDROID_VNDK__ können andere cflags oder cppflags in Android.bp angegeben werden. Die in cppflags angegebenen cflags oder target.vendor sind 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 dies ist das Code-Listing von 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

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 die exportierten Symbole

Der VNDK-ABI-Checker vergleicht die ABI von VNDK-Anbietervarianten und VNDK-Erweiterungen mit den Referenz-ABI-Dumps unter prebuilts/abi-dumps/vndk .

  • Von VNDK-Anbietervarianten exportierte Symbole (z. B. /apex/com.android.vndk.v${VER}/lib[64]/libexample.so ) müssen mit den in ABI-Dumps definierten Symbolen identisch sein (nicht die Obermenge davon).
  • Von VNDK-Erweiterungen exportierte Symbole (z. B. /vendor/lib[64]/vndk/libexample.so ) müssen Obermengen der in ABI-Dumps definierten Symbole sein.

Wenn VNDK-Anbietervarianten oder VNDK-Erweiterungen die oben genannten Anforderungen nicht erfüllen, gibt die VNDK-ABI-Prüfung Build-Fehler aus und stoppt den Build.

Ausschließen von Quelldateien oder gemeinsam genutzten Bibliotheken von Anbietervarianten

Um Quelldateien von der Herstellervariante auszuschließen, fügen Sie sie der Eigenschaft exclude_srcs . Um sicherzustellen, dass gemeinsam genutzte Bibliotheken nicht mit der Anbietervariante verknüpft werden, fügen Sie diese Bibliotheken in ähnlicher Weise zur Eigenschaft exclude_shared_libs . Zum 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 enthält die Kernvariante von libexample_cond_exclude den Code von fwk.c und both.c und hängt von den gemeinsam genutzten Bibliotheken libfwk_only und libboth . Die Herstellervariante von libexample_cond_exclude enthält nur den Code von both.c da fwk.c durch die Eigenschaft exclude_srcs ausgeschlossen wird. In ähnlicher Weise hängt es nur von der gemeinsam genutzten Bibliothek libboth da libfwk_only durch die Eigenschaft exclude_shared_libs ausgeschlossen wird.

Exportieren Sie Header von VNDK-Erweiterungen

Eine VNDK-Erweiterung kann einer gemeinsam genutzten VNDK-Bibliothek neue Klassen oder neue Funktionen hinzufügen. Es wird empfohlen, diese Deklarationen in unabhängigen Headern zu belassen und die bestehenden Header nicht zu ändern.

Beispielsweise wird eine neue Header-Datei include-ext/example/ext/feature_name.h für die VNDK-Erweiterung libexample_ext :

  • Android.bp
  • include-ext/example/ext/feature_name.h
  • include/beispiel/beispiel.h
  • src/example.c
  • src/ext/feature_name.c

In der folgenden Android.bp exportieren libexample nur , wohingegen libexample_ext sowohl include als include include-ext exportiert. Dadurch wird sichergestellt, dass feature_name.h von den Benutzern von libexample nicht fälschlicherweise eingefügt wird:

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 das Trennen von Erweiterungen in unabhängige Header-Dateien nicht möglich ist, besteht eine Alternative darin, #ifdef Wächter hinzuzufügen. Stellen Sie jedoch sicher, dass alle Benutzer der VNDK-Erweiterung die Define-Flags hinzufügen. Sie können cc_defaults definieren, um cflags Define-Flags hinzuzufügen und gemeinsam genutzte Bibliotheken mit cflags zu shared_libs .

Um beispielsweise eine neue Member-Funktion Example2::get_b() zur VNDK-Erweiterung libexample2_ext , müssen Sie die vorhandene Header-Datei ändern und einen #ifdef Wächter hinzufügen:

#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_

Für die Benutzer von libexample2_ext ist ein cc_defaults namens libexample2_ext_defaults definiert:

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 Benutzer von libexample2_ext können einfach libexample2_ext_defaults in ihre Eigenschaft defaults aufnehmen:

cc_binary {
    name: "example2_user_executable",
    defaults: ["libexample2_ext_defaults"],
    vendor: true,
}

Produktpakete

Im Android-Buildsystem gibt die Variable PRODUCT_PACKAGES die ausführbaren Dateien, gemeinsam genutzten Bibliotheken oder Pakete an, die auf dem Gerät installiert werden sollen. Die transitiven Abhängigkeiten der angegebenen Module werden implizit ebenfalls in das Gerät installiert.

Wenn BOARD_VNDK_VERSION aktiviert ist, erhalten Module mit vendor_available oder vndk.enabled eine Sonderbehandlung. Wenn ein Framework-Modul von einem Modul mit vendor_available oder vndk.enabled , ist die Core-Variante im transitiven Installationssatz enthalten. Wenn ein Anbietermodul von einem Modul mit Anbieter_verfügbar vendor_available , ist die Anbietervariante im transitiven Installationssatz enthalten. Anbietervarianten von Modulen mit vndk.enabled werden jedoch unabhängig davon installiert, ob sie von Anbietermodulen verwendet werden oder nicht.

Wenn die Abhängigkeiten für das Build-System unsichtbar sind (z. B. gemeinsam genutzte Bibliotheken, die zur Laufzeit mit dlopen() geöffnet werden können), sollten Sie die Modulnamen in PRODUCT_PACKAGES , um diese Module explizit zu installieren.

Wenn ein Modul einen vendor_available oder vndk.enabled hat, steht der Modulname für seine Kernvariante. Um die Herstellervariante explizit in PRODUCT_PACKAGES , hängen Sie das Suffix .vendor an den Modulnamen an. Zum 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 . Um /vendor/lib[64]/libexample.so zu installieren, fügen libexample.vendor zu PRODUCT_PACKAGES :

PRODUCT_PACKAGES += libexample.vendor