Supporto del sistema di build VNDK

In Android 8.1 e versioni successive, il sistema di compilazione ha il supporto VNDK integrato. Quando Il supporto VNDK è abilitato, il sistema di build controlla le dipendenze tra moduli, crea una variante specifica del fornitore per i moduli del fornitore e installa automaticamente quei moduli in directory designate.

Esempio di supporto di build VNDK

In questo esempio, la definizione del modulo Android.bp definisce una libreria denominata libexample. vendor_available indica che i moduli del framework e quelli del fornitore possono dipendere libexample:

libexample seller_available:true e vndk.enabled:true

Supporto Figura 1. attivato.

Sia l'eseguibile del framework /system/bin/foo che il fornitore gli eseguibili /vendor/bin/bar dipendono da libexample e hanno libexample nelle loro proprietà shared_libs.

Se libexample viene utilizzato sia dai moduli del framework sia dal fornitore vengono create due varianti di libexample. La variante principale (denominato dopo libexample) viene utilizzato dai moduli framework e la variante del fornitore (denominata dopo libexample.vendor) viene utilizzata dal fornitore moduli. Le due varianti sono installate in directory diverse:

  • La variante principale è installata /system/lib[64]/libexample.so.
  • La variante del fornitore è installata in VNDK APEX perché vndk.enabled è true.

Per maggiori dettagli, vedi Definizione del modulo.

Configura il supporto per le build

Per abilitare il supporto completo del sistema di compilazione per un dispositivo del prodotto, aggiungi Da BOARD_VNDK_VERSION a BoardConfig.mk:

BOARD_VNDK_VERSION := current

Questa impostazione ha un effetto global: se definita in BoardConfig.mk, tutti i moduli sono selezionati. Poiché non esiste alcun meccanismo inserire un modulo in questione nella blacklist o nella lista consentita, è necessario pulire tutti dipendenze non necessarie prima di aggiungere BOARD_VNDK_VERSION. Tu può testare e compilare un modulo impostando BOARD_VNDK_VERSION in le variabili di ambiente:

$ BOARD_VNDK_VERSION=current m module_name.vendor

Quando il criterio BOARD_VNDK_VERSION è abilitato, diverse impostazioni globali predefinite percorsi di ricerca delle intestazioni vengono rimossi. tra cui:

  • 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

Se un modulo dipende dalle intestazioni di queste directory, devi specificare (esplicitamente) le dipendenze con header_libs, static_libs e/o shared_libs.

APEX VNDK

In Android 10 e versioni precedenti, i moduli con vndk.enabled sono stati installati in /system/lib[64]/vndk[-sp]-${VER}. In Android 11 e versioni successive, Le librerie VNDK sono pacchettizzate in formato APEX e il nome VNDK APEX è com.android.vndk.v${VER}. A seconda della configurazione del dispositivo, VNDK APEX è lineato o non appiattito ed è disponibile nel percorso canonico /apex/com.android.vndk.v${VER}.

APEX VNDK

Figura 2. VNDK APEX

Definizione del modulo

Per creare Android con BOARD_VNDK_VERSION, devi rivedere il della definizione del modulo in Android.mk o Android.bp. Questa sezione descrive i diversi tipi di moduli definizioni, varie proprietà dei moduli relativi a VNDK e controlli delle dipendenze implementato nel sistema di compilazione.

Moduli dei fornitori

I moduli del fornitore sono librerie condivise o eseguibili specifici del fornitore che deve essere installato in una partizione del fornitore. In Android.bp file, I moduli del fornitore devono impostare il fornitore o la proprietà di proprietà su true. In Android.mk file, i moduli del fornitore devono impostare LOCAL_VENDOR_MODULE o LOCAL_PROPRIETARY_MODULE per true.

Se BOARD_VNDK_VERSION viene definito, il sistema di compilazione non consente le dipendenze tra i moduli del fornitore e i moduli del framework ed emette errori se:

  • un modulo senza vendor:true dipende da un modulo con vendor:true, oppure
  • un modulo con vendor:true dipende da un modulo non llndk_library che non contiene né vendor:true o vendor_available:true.

Il controllo delle dipendenze si applica a header_libs, static_libs e shared_libs pollici Android.bp e a LOCAL_HEADER_LIBRARIES, LOCAL_STATIC_LIBRARIES e LOCAL_SHARED_LIBRARIES in Android.mk.

LL-NDK

Le librerie condivise LL-NDK sono librerie condivise con ABI stabili. Entrambi i framework e i moduli del fornitore condividono la stessa e la più recente implementazione. Per ogni nella libreria condivisa LL-NDK, il cc_library contiene un Proprietà llndk con un file di simboli:

cc_library {
    name: "libvndksupport",
    llndk: {
        symbol_file: "libvndksupport.map.txt",
    },
}

Il file dei simboli descrive i simboli visibili nei moduli del fornitore. Ad esempio:

LIBVNDKSUPPORT {
  global:
    android_load_sphal_library; # llndk
    android_unload_sphal_library; # llndk
  local:
    *;
};

In base al file dei simboli, il sistema di compilazione genera una libreria condivisa stub per moduli del fornitore, che si collegano a queste librerie BOARD_VNDK_VERSION è abilitato. Nello stub è incluso un simbolo libreria condivisa solo se:

  • Non sia definito nella sezione che termina con _PRIVATE o _PLATFORM,
  • Non ha il tag #platform-only e
  • Non presenta tag #introduce* o il tag corrisponde ai target.
di Gemini Advanced.

VNDK

In Android.bp file, cc_library, cc_library_static, cc_library_shared e Le definizioni del modulo cc_library_headers supportano tre modelli correlati a VNDK proprietà: vendor_available, vndk.enabled e vndk.support_system_process.

Se vendor_available o vndk.enabled è true, si possono avere due varianti (principale e fornitore) l'IA generativa. La variante principale deve essere trattata come un modulo del framework e il fornitore la variante deve essere trattata come un modulo del fornitore. Se alcuni moduli del framework dipendono In questo modulo, viene creata la variante principale. Se alcuni moduli del fornitore dipendono da questo modulo, viene creata la variante del fornitore. Il sistema di compilazione applica i seguenti controlli di dipendenza:

  • La variante principale è sempre solo framework e inaccessibile al fornitore moduli.
  • La variante del fornitore è sempre inaccessibile ai moduli del framework.
  • Tutte le dipendenze della variante del fornitore, che sono specificate in header_libs, static_libs e/o shared_libs, deve essere llndk_library o un modulo con vendor_available o vndk.enabled.
  • Se vendor_available è true, la variante del fornitore sia accessibile a tutti i moduli del fornitore.
  • Se vendor_available è false, la variante del fornitore è accessibile solo ad altri moduli VNDK o VNDK-SP (ovvero, moduli con vendor:true non può collegare vendor_available:false moduli).

Il percorso di installazione predefinito per cc_library o Il valore di cc_library_shared è determinato dalle seguenti regole:

  • La variante principale è installata su /system/lib[64].
  • Il percorso di installazione della variante del fornitore può variare:
    • Se vndk.enabled è false, la variante del fornitore è installato in /vendor/lib[64].
    • Se vndk.enabled è true, la variante del fornitore è installato in VNDK APEX(com.android.vndk.v${VER}).

La tabella riportata di seguito riassume il modo in cui il sistema di compilazione gestisce le varianti del fornitore:

fornitore_disponibile vndk
attivato
vndk
support_same_process
Descrizioni delle varianti del fornitore
true false false Le varianti del fornitore sono SOLO VND. Le librerie condivise installato in /vendor/lib[64].
true Non valido (errore di build)
true false Le varianti del fornitore sono VNDK. Le librerie condivise sono installate a VNDK APEX.
true Le varianti del fornitore sono VNDK-SP. Le librerie condivise installato in VNDK APEX.

false

false

false

Nessuna variante del fornitore. Questo modulo è SOLO FWK.

true Non valido (errore di build)
true false Le varianti del fornitore sono VNDK-Private. Le librerie condivise installato in VNDK APEX. Questi dati non devono essere direttamente utilizzati dai moduli del fornitore.
true Le varianti del fornitore sono VNDK-SP-Private. Le librerie condivise installato in VNDK APEX. Questi dati non devono essere direttamente utilizzati dai moduli del fornitore.

Estensioni VNDK

Le estensioni VNDK sono librerie condivise VNDK con API aggiuntive. Le estensioni sono installata in /vendor/lib[64]/vndk[-sp] (senza suffisso di versione) ed eseguire l'override delle librerie condivise VNDK originali in fase di runtime.

Definizione delle estensioni VNDK

Su Android 9 e versioni successive, Android.bp supporta VNDK in modo nativo estensioni. Per creare un'estensione VNDK, definisci un altro modulo con un vendor:true e una proprietà extends:

cc_library {
    name: "libvndk",
    vendor_available: true,
    vndk: {
        enabled: true,
    },
}

cc_library {
    name: "libvndk_ext",
    vendor: true,
    vndk: {
        enabled: true,
        extends: "libvndk",
    },
}

Un modulo con vendor:true, vndk.enabled:true e Le proprietà extends definiscono l'estensione VNDK:

  • La proprietà extends deve specificare una libreria condivisa VNDK di base (o nome della libreria condivisa VNDK-SP).
  • Le estensioni VNDK (o estensioni VNDK-SP) prendono il nome dal modulo di base a cui si estendono. Ad esempio, il file binario di output libvndk_ext è libvndk.so invece di libvndk_ext.so.
  • Le estensioni VNDK sono installate in /vendor/lib[64]/vndk.
  • Le estensioni VNDK-SP sono installate /vendor/lib[64]/vndk-sp.
  • Le librerie condivise di base devono avere vndk.enabled:true e vendor_available:true.

Un'estensione VNDK-SP deve estendersi da una libreria condivisa VNDK-SP (vndk.support_system_process deve essere uguale a):

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

Le estensioni VNDK (o estensioni VNDK-SP) possono dipendere dall'utilizzo condiviso da altri fornitori librerie:

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

Usare le estensioni VNDK

Se un modulo del fornitore dipende da API aggiuntive definite dalle estensioni VNDK, deve specificare il nome dell'estensione VNDK nel shared_libs proprietà:

// 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",
    ],
}

Se un modulo del fornitore dipende dalle estensioni VNDK, queste vengono installata su /vendor/lib[64]/vndk[-sp] automaticamente. Se un modulo non dipende più da un'estensione VNDK, aggiungi un passaggio pulito CleanSpec.mk per rimuovere la libreria condivisa. Ad esempio:

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

Compilazione condizionale

Questa sezione descrive come gestire le piccole differenze (ad es. l'aggiunta o la rimozione di una caratteristica da una delle varianti) tra i seguenti: tre librerie condivise VNDK:

  • Variante principale (ad es. /system/lib[64]/libexample.so)
  • Variante del fornitore (ad es. /apex/com.android.vndk.v${VER}/lib[64]/libexample.so)
  • Estensione VNDK (ad es. /vendor/lib[64]/vndk[-sp]/libexample.so)

Flag del compilatore condizionali

Il sistema di compilazione di Android definisce __ANDROID_VNDK__ per il fornitore varianti ed estensioni VNDK per impostazione predefinita. Puoi proteggere il codice con i sistemi di protezione del preprocessore C:

void all() { }

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

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

Oltre a __ANDROID_VNDK__, diverse cflags o cppflags può essere specificato in Android.bp. La cflags o cppflags specificati in target.vendor è specifico per la variante del fornitore.

Ad esempio, il seguente valore Android.bp definisce libexample e 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",
    ],
}

Questo è l'elenco di codice di 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

In base a questi due file, il sistema di compilazione genera librerie condivise con i seguenti simboli esportati:

Percorso di installazione Simboli esportati
/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 e vndk_ext

Requisiti relativi ai simboli esportati

Lo strumento di verifica ABI VNDK confronta l'ABI delle varianti del fornitore VNDK e Estensioni VNDK ai dump dell'ABI di riferimento in prebuilts/abi-dumps/vndk.

  • Simboli esportati dalle varianti del fornitore VNDK (ad es. /apex/com.android.vndk.v${VER}/lib[64]/libexample.so) deve essere identico e non i superinsiemi dei simboli definiti nei dump dell'ABI.
  • Simboli esportati dalle estensioni VNDK (ad es. /vendor/lib[64]/vndk/libexample.so) devono essere soprainsiemi del e i simboli definiti nei dump dell'ABI.

Se le varianti del fornitore VNDK o le estensioni VNDK non seguono i requisiti di cui sopra, il controllo ABI VNDK emette errori di generazione e blocca creare.

Escludere file di origine o librerie condivise dalle varianti del fornitore

Per escludere i file di origine dalla variante del fornitore, aggiungili alla sezione exclude_srcs proprietà. Analogamente, per garantire che le librerie condivise non collegate alla variante del fornitore, aggiungi queste librerie alla exclude_shared_libs proprietà. Ad esempio:

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 questo esempio, la variante principale di libexample_cond_exclude include il codice di fwk.c e both.c e dipende nelle raccolte condivise libfwk_only e libboth. La la variante del fornitore di libexample_cond_exclude include solo il codice da both.c perché fwk.c è escluso dal exclude_srcs proprietà. Analogamente, dipende solo dalla libreria condivisa libboth perché libfwk_only è escluso dal proprietà exclude_shared_libs.

Esporta intestazioni dalle estensioni VNDK

Un'estensione VNDK può aggiungere nuove classi o nuove funzioni a una VNDK condivisa libreria. Si consiglia di conservare queste dichiarazioni in intestazioni indipendenti senza modificare le intestazioni esistenti.

Ad esempio, un nuovo file di intestazione Creazione di include-ext/example/ext/feature_name.h per la VNDK estensione libexample_ext:

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

Nel seguente Android.bp, libexample esportazioni solo include, mentre libexample_ext esporta entrambi include e include-ext. Ciò garantisce feature_name.h non verrà incluso in modo errato dagli utenti di 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",
    },
}

Se non è possibile separare le estensioni in file di intestazione indipendenti, un'alternativa è aggiungere #ifdef sistemi di protezione. Tuttavia, assicurati che tutti Gli utenti dell'estensione VNDK aggiungono i flag di definizione. Puoi definire cc_defaults per aggiungere flag di definizione a cflags e collegare raccolte condivise con shared_libs.

Ad esempio, per aggiungere una nuova funzione membro Example2::get_b() a l'estensione VNDK libexample2_ext, devi modificare il campo esistente di intestazione e aggiungi una protezione #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 di nome libexample2_ext_defaults è definita per gli utenti di 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",
    ],
}

Gli utenti di libexample2_ext possono semplicemente includere libexample2_ext_defaults nel suo defaults proprietà:

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

Pacchetti di prodotti

Nel sistema di compilazione Android, la variabile PRODUCT_PACKAGES specifica gli eseguibili, le librerie condivise o i pacchetti che devono essere installato nel dispositivo. Le dipendenze transitive del parametro specificato sono anch'essi implicitamente installati nel dispositivo.

Se il criterio BOARD_VNDK_VERSION è abilitato, i moduli con vendor_available o vndk.enabled di sconto trattamento. Se un modulo del framework dipende da un modulo con vendor_available o vndk.enabled, la variante principale è incluso nel set di installazione transitivo. Se un modulo del fornitore dipende da un modulo con vendor_available, la variante del fornitore è incluso nel set di installazione transitivo. Tuttavia, le varianti dei moduli del fornitore con vndk.enabled vengono installati a prescindere che siano utilizzati o meno dai moduli del fornitore.

Quando le dipendenze sono invisibili al sistema di compilazione (ad es.le librerie condivise). che può essere aperto con dlopen() in runtime), è necessario specificare i nomi dei moduli in PRODUCT_PACKAGES per installare questi moduli in modo esplicito.

Se un modulo ha vendor_available o vndk.enabled, il nome del modulo indica la variante principale. Per specificare esplicitamente variante del fornitore in PRODUCT_PACKAGES, aggiungi un .vendor al nome del modulo. Ad esempio:

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

In questo esempio, libexample sta per /system/lib[64]/libexample.so e libexample.vendor è l'acronimo di /vendor/lib[64]/libexample.so. Per installare /vendor/lib[64]/libexample.so, aggiungi libexample.vendor a PRODUCT_PACKAGES:

PRODUCT_PACKAGES += libexample.vendor