VNDK-Build-Systemunterstützung

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 den Modulen, erstellt eine herstellerspezifische Variante für Herstellermodule und installiert diese Module automatisch in dafür vorgesehenen Verzeichnissen.

Beispiel für VNDK-Build-Unterstützung

In diesem Beispiel wird die Android.bp definiert Moduldefinition eine Bibliothek mit dem Namen libexample . Die vendor_available Eigenschaft gibt Rahmenmodule und Lieferantenmodule auf abhängen libexample :

libexample provider_available:true und vndk.enabled:true

Abbildung 1. VNDK Unterstützung aktiviert

Sowohl der Rahmen ausführbare /system/bin/foo und der Verkäufer ausführbaren /vendor/bin/bar hängen von libexample und haben libexample in ihren shared_libs Eigenschaften.

Wenn libexample von beiden Rahmenmodule und Lieferantenmodule verwendet wird, zwei Varianten der libexample gebaut. Die Kern - Variante (benannt nach libexample ) durch Rahmenmodule und der Verkäufer Variante (benannt nach verwendet libexample.vendor ) durch Lieferantenmodule verwendet. Die beiden Varianten werden in unterschiedliche Verzeichnisse installiert:

  • Die Kern - Variante ist in installiert /system/lib[64]/libexample.so .
  • Der Verkäufer Variante ist in VNDK APEX installiert , da vndk.enabled ist true .

Weitere Einzelheiten finden Sie Module Definition .

Build-Unterstützung konfigurieren

So aktivieren Sie volle Build - System Unterstützung für eine Produktvorrichtung, fügt BOARD_VNDK_VERSION zu BoardConfig.mk :

BOARD_VNDK_VERSION := current

Diese Einstellung hat einen globalen Effekt: Wenn in definierten BoardConfig.mk alle Module überprüft werden. Da es keinen Mechanismus , um schwarze Liste oder weiße Liste einer beleidigenden Modul ist, sollten Sie alle unnötigen Abhängigkeiten reinigen , bevor das Hinzufügen BOARD_VNDK_VERSION . Sie können durch das Setzen eines Moduls testen und kompilieren BOARD_VNDK_VERSION in Ihrer Umgebungsvariablen:

$ BOARD_VNDK_VERSION=current m module_name.vendor

Wenn BOARD_VNDK_VERSION aktiviert ist, werden mehrere globale Standard 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 auf dem Header aus diesen Verzeichnissen hängt, müssen Sie angeben (explizit) die Abhängigkeiten mit header_libs , static_libs und / oder shared_libs .

VNDK-APEX

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

VNDK-APEX

Abbildung 2. VNDK APEX

Moduldefinition

Zu bauen Android mit BOARD_VNDK_VERSION , müssen Sie die Moduldefinition revidieren entweder 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, Lieferantenmodule müssen Anbieter oder proprietäre Eigenschaft festlegen true . In Android.mk Dateien, Lieferantenmodule müssen eingestellt LOCAL_VENDOR_MODULE oder LOCAL_PROPRIETARY_MODULE zu true .

Wenn BOARD_VNDK_VERSION definiert ist, nicht zulässt , das Build - System von Abhängigkeiten zwischen Lieferantenmodule und Rahmenmodule und gibt Fehler , wenn:

  • ein Modul ohne vendor:true , hängt von einem Modul mit vendor:true , oder
  • ein Modul mit vendor:true ist abhängig von einem Nicht - llndk_library Modul , das weder hat vendor:true , noch vendor_available:true .

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

LL-NDK

LL-NDK Shared Libraries sind Shared Libraries mit stabilen ABIs. Sowohl Framework- als auch Anbietermodule verwenden dieselbe und die neueste Implementierung. Für jede LL-NDK Bibliothek geteilt, Android.bp enthält eine llndk_library Moduldefinition:

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

Diese Moduldefinition spezifiziert einen Modulnamen und eine Symboldatei, 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, erzeugt das Bausystem eine Stub gemeinsam benutzte Bibliothek für Lieferantenmodule, die mit diesen Bibliotheken verknüpfen , wenn BOARD_VNDK_VERSION aktiviert ist. Ein Symbol wird nur dann in die gemeinsam genutzte Stub-Bibliothek aufgenommen, wenn es:

  • Ist das nicht im Abschnitt Ende definiert mit _PRIVATE oder _PLATFORM ,
  • Hat nicht #platform-only - Tag, und
  • Hat nicht #introduce* Tags oder die Tag - Matches mit dem Ziel.

VNDK

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

Wenn vendor_available oder vndk.enabled ist true , zwei Varianten (Kern- und Lieferant) kann gebaut 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 gebaut. 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 nur ein Framework und für Herstellermodule nicht zugänglich.
  • Die Vendor-Variante ist für Framework-Module immer unzugänglich.
  • Alle Abhängigkeiten des Verkäufers Variante, die in angegeben sind header_libs , static_libs und / oder shared_libs , muss entweder eine sein llndk_library oder ein Modul mit vendor_available oder vndk.enabled .
  • Wenn vendor_available ist true , ist der Anbieter Variante für alle Lieferantenmodule zugänglich.
  • Wenn vendor_available ist false , ist der Verkäufer Variante nur zugänglich für andere VNDK oder VNDK-SP - Module (dh Module mit vendor:true kein Link vendor_available:false Module).

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

  • Die Kernvariante wird installiert /system/lib[64] .
  • Der Installationspfad der Anbietervariante kann variieren:
    • Wenn vndk.enabled ist false , ist der Verkäufer Variante installiert in /vendor/lib[64] .
    • Wenn vndk.enabled ist true , so ist der Verkäufer Variante in VNDK APEX (installiert com.android.vndk.v${VER} ).

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

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

false

false

false

Keine Anbietervarianten. Dieses Modul ist FWK-ONLY.

true Ungültig (Build - Fehler)
true false Die Anbieter Varianten sind VNDK-Privat. Gemeinsam genutzte Bibliotheken werden in VNDK APEX installiert. Diese dürfen nicht direkt von Herstellermodulen verwendet werden.
true Die Anbieter Varianten sind VNDK-SP-Privat. 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 sind installiert /vendor/lib[64]/vndk[-sp] (ohne Version Suffix) und die ursprüngliche VNDK zur Laufzeit gemeinsam genutzten Bibliotheken außer Kraft setzen.

Definieren von VNDK-Erweiterungen

In Android 9 und höher, Android.bp nativ unterstützt VNDK Erweiterungen. Um eine Erweiterung VNDK zu bauen, definiert ein weiteres Modul mit einem vendor:true und eine extends 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 vendor:true , vndk.enabled:true und extends Eigenschaften der VNDK Erweiterung definiert:

  • Das extends Eigenschaft muss eine Basis VNDK Shared Library - Namen angeben (oder VNDK-SP Shared Library Name).
  • VNDK-Erweiterungen (oder VNDK-SP-Erweiterungen) werden nach den Basismodulnamen benannt, von denen sie ausgehen. Zum Beispiel kann die Ausgabe binär von libvndk_ext ist libvndk.so statt libvndk_ext.so .
  • VNDK Erweiterungen installiert sind , in /vendor/lib[64]/vndk .
  • VNDK-SP - Erweiterungen installiert sind , in /vendor/lib[64]/vndk-sp .
  • Die Basis gemeinsam genutzte Bibliotheken müssen beide vndk.enabled:true und vendor_available:true .

A VNDK-SP Erweiterung muss sich von einem VNDK-SP gemeinsam benutzte Bibliothek ( 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,
}

VNDK-Erweiterungen verwenden

Wenn ein Lieferantenmodul auf zusätzliche APIs abhängig von VNDK Erweiterungen definiert, muss das Modul den Namen der VNDK Erweiterung angeben in seiner shared_libs Eigenschaft:

// 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 Lieferantenmodul auf VNDK Erweiterungen abhängig ist , werden diese VNDK Erweiterungen installiert /vendor/lib[64]/vndk[-sp] automatisch. Wenn ein Modul nicht mehr von einer VNDK Erweiterung, einen sauberen Schritt hinzuzufügen CleanSpec.mk die gemeinsame 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 die feinen Unterschiede behandeln (zB das Hinzufügen oder ein Feature von einer der Varianten zu entfernen) zwischen den folgenden drei VNDK Shared Libraries:

  • Kernvariante (zB /system/lib[64]/libexample.so )
  • Vendor Variante (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 - Build - System definiert __ANDROID_VNDK__ für Anbieter Varianten und VNDK Erweiterungen standardmäßig aktiviert . Sie können den Code mit den C-Präprozessor-Guards schützen:

void all() { }

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

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

Neben __ANDROID_VNDK__ verschiedene cflags oder cppflags kann angegeben werden Android.bp . Die cflags oder cppflags in bestimmten target.vendor ist spezifisch für die Anbieter Variante.

Zum Beispiel kann die folgende Android.bp definiert 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 die Codeliste 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

Die VNDK ABI Prüfer vergleicht die ABI von VNDK Anbieter Varianten und VNDK Erweiterungen der Referenz ABI - Dumps unter prebuilts/abi-dumps/vndk .

  • Symbole exportiert von VNDK Anbieter Varianten (zB /apex/com.android.vndk.v${VER}/lib[64]/libexample.so ) muss (nicht die Obermengen) die Symbole definiert in ABI - Dumps identisch sein.
  • Symbole exportiert von VNDK Erweiterungen (zB /vendor/lib[64]/vndk/libexample.so ) müssen in ABI - Dumps definiert eine Obermenge der Symbole sein.

Wenn VNDK Anbieter Varianten oder VNDK Erweiterungen nicht den Anforderungen oben, VNDK ABI Checker aussendet Fehler bauen folgen und stoppt den Build.

Ausschließen von Quelldateien oder gemeinsam genutzten Bibliotheken von Anbietervarianten

Um Quelldateien vom Hersteller Variante, fügen sie den Ausschluß exclude_srcs Eigenschaft. In ähnlicher Weise , um sicherzustellen , gemeinsam genutzte Bibliotheken sind nicht mit der Anbieter Variante verknüpft, diese Bibliotheken zur hinzufügen exclude_shared_libs Eigenschaft. 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 wird die Kernvariante libexample_cond_exclude enthält den Code aus fwk.c und both.c und hängt von den gemeinsamen genutzten Bibliotheken libfwk_only und libboth . Der Verkäufer Variante libexample_cond_exclude enthält nur den Code aus both.c weil fwk.c durch die ausgeschlossen ist exclude_srcs Eigenschaft. In ähnlicher Weise kommt es nur auf der gemeinsam genutzten Bibliothek libboth weil libfwk_only durch die ausgeschlossen ist exclude_shared_libs Eigenschaft.

Header aus VNDK-Erweiterungen exportieren

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 beizubehalten und eine Änderung der vorhandenen Header zu vermeiden.

Zum Beispiel kann eine neue Header - Datei include-ext/example/ext/feature_name.h für die VNDK Erweiterung erstellt libexample_ext :

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

Im folgenden Android.bp , libexample Exporte nur include , während libexample_ext Ausfuhren beide include und include-ext . Dadurch wird sichergestellt , feature_name.h nicht falsch von den Benutzern aufgenommen werden 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 Erweiterungen unabhängige Header - Dateien Trennung nicht möglich ist, ist eine Alternative hinzuzufügen #ifdef Wachen. Stellen Sie jedoch sicher, dass alle Benutzer der VNDK-Erweiterung die Define-Flags hinzufügen. Sie können definieren cc_defaults hinzufügen Flags definieren cflags und Link Shared Libraries mit shared_libs .

Um zum Beispiel eine neue Member - Funktion hinzufügen Example2::get_b() zum VNDK Erweiterung libexample2_ext , müssen Sie die vorhandene Header - Datei ändern und fügen Sie ein #ifdef Wache:

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

Ein cc_defaults namens libexample2_ext_defaults ist für die Benutzer definiert 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 kann einfach schließen libexample2_ext_defaults in ihren defaults Eigenschaft:

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

Produktpakete

Im Android - Build - System, wird die Variable PRODUCT_PACKAGES gibt an den ausführbaren Dateien, gemeinsam genutzte Bibliotheken oder Pakete , die in das Gerät installiert werden sollen. Auch die transitiven Abhängigkeiten der angegebenen Module werden implizit in das Gerät eingebaut.

Wenn BOARD_VNDK_VERSION aktiviert ist, Module mit vendor_available oder vndk.enabled besondere Behandlung. Wenn ein Rahmenmodul auf einem Modul mit hängt vendor_available oder vndk.enabled wird die Kernvariante in dem transitiven Installation Set enthält. Wenn ein Lieferantenmodul auf einem Modul mit hängt vendor_available ist der Verkäufer Variante in dem transitiven Installation Set enthält. Allerdings Anbieter Varianten von Modulen mit vndk.enabled installiert sind , ob sie von Lieferantenmodule verwendet werden.

Wenn die Abhängigkeiten zu dem Build - System unsichtbar sind (zB gemeinsam genutzte Bibliotheken , die mit geöffnet werden können dlopen() in der Laufzeit), sollten Sie die Modulnamen in angeben PRODUCT_PACKAGES explizit die Module zu installieren.

Wenn ein Modul hat vendor_available oder vndk.enabled , steht der Modulname für seine Kernvariante. Um explizit die Anbieter Variante angeben PRODUCT_PACKAGES , append ein .vendor Suffix zu dem Modulnamen. Zum Beispiel:

cc_library {
    name: "libexample",
    srcs: ["example.c"],
    vendor_available: true,
}

In diesem Beispiel libexample steht für /system/lib[64]/libexample.so und libexample.vendor steht für /vendor/lib[64]/libexample.so . So installieren Sie /vendor/lib[64]/libexample.so , fügen libexample.vendor zu PRODUCT_PACKAGES :

PRODUCT_PACKAGES += libexample.vendor