W Androidzie 8.1 i nowszych system kompilacji ma wbudowaną obsługę VNDK. Kiedy Włączona jest obsługa VNDK, system kompilacji sprawdza zależności między tworzy wersję dla modułów dostawcy oraz automatycznie instaluje te moduły w wyznaczonych katalogach.
Przykład obsługi kompilacji VNDK
W tym przykładzie definicja modułu Android.bp
definiuje
o nazwie libexample
. vendor_available
wskazuje, że moduły platformy i dostawcy mogą zależeć od
libexample
:
Rys.1. Włączona obsługa
Zarówno plik wykonywalny platformy /system/bin/foo
, jak i dostawca
wykonywalny /vendor/bin/bar
zależą od elementów libexample
i
mają libexample
w swoich usługach shared_libs
.
Jeśli interfejs libexample
jest używany zarówno przez moduły platformy, jak i dostawcę
2 moduły, 2 wersje funkcji libexample
. Wariant podstawowy
(nazwany od libexample
) jest używana przez moduły platformy, a metoda
wersja dostawcy (o nazwie libexample.vendor
) jest używana przez dostawcę.
modułów. Te 2 wersje są instalowane w różnych katalogach:
- Wariant podstawowy jest instalowany w
/system/lib[64]/libexample.so
- Wariant dostawcy jest instalowany w VNDK APEX, ponieważ
Obecny stan „
vndk.enabled
”:true
.
Aby dowiedzieć się więcej, zapoznaj się z definicją modułu.
Skonfiguruj pomoc dotyczącą kompilacji
Aby włączyć pełną obsługę systemu kompilacji na urządzeniu usługi, dodaj
Od BOARD_VNDK_VERSION
do BoardConfig.mk
:
BOARD_VNDK_VERSION := current
To ustawienie ma efekt globalny: jeśli jest zdefiniowane w
BoardConfig.mk
, wszystkie moduły są zaznaczone. Ze względu na brak mechanizmu
do czarnej lub białej listy modułów naruszających zasady, wyczyść wszystkie
przed dodaniem niepotrzebnych zależności (BOARD_VNDK_VERSION
). Ty
może testować i skompilować moduł, ustawiając BOARD_VNDK_VERSION
w
zmienne środowiskowe:
$ BOARD_VNDK_VERSION=current m module_name.vendor
Po włączeniu funkcji BOARD_VNDK_VERSION
kilka domyślnych ustawień globalnych
ścieżki wyszukiwania w nagłówku są usuwane. Należą do nich:
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
Jeśli moduł wymaga nagłówków z tych katalogów, musisz określić
(wyraźnie) zależności z elementem header_libs
,
static_libs
lub shared_libs
.
VNDK APEX
W Androidzie 10 i starszych wersjach moduły z rozszerzeniem vndk.enabled
zostały zainstalowane w
/system/lib[64]/vndk[-sp]-${VER}
Na Androidzie 11 i nowszych
Biblioteki VNDK są spakowane w formacie APEX, a nazwa VNDK APEX to
com.android.vndk.v${VER}
W zależności od konfiguracji urządzenia
Obszar VNDK APEX jest spłaszczony lub niespłaszczony i jest dostępny ze ścieżki kanonicznej.
/apex/com.android.vndk.v${VER}
Rysunek 2. VNDK APEX.
Definicja modułu
Aby utworzyć Androida w wersji BOARD_VNDK_VERSION
, musisz zmienić
definicji modułu w Android.mk
albo
Android.bp
W tej sekcji opisujemy różne rodzaje modułów
definicje, kilka właściwości modułu związanych z VNDK oraz testy zależności
zaimplementowaliśmy w systemie kompilacji.
Moduły dostawcy
Moduły dostawcy to specyficzne dla dostawcy pliki wykonywalne lub biblioteki udostępnione,
musi być zainstalowany na partycji dostawcy. W plikach Android.bp
moduły dostawcy muszą ustawić dostawcę lub zastrzeżoną właściwość na true
.
W plikach Android.mk
należy określić moduły dostawcy
LOCAL_VENDOR_MODULE
lub LOCAL_PROPRIETARY_MODULE
do
true
Jeśli zdefiniowano BOARD_VNDK_VERSION
, system kompilacji zabrania
zależności między modułami dostawcy i modułami platformy oraz generuje błędy, jeśli:
- moduł bez
vendor:true
zależy od modułu zvendor:true
lub - moduł z funkcją
vendor:true
zależy od moduł inny niżllndk_library
, który nie zawiera żadnegovendor:true
anivendor_available:true
.
Sprawdzanie zależności ma zastosowanie do tych reguł: header_libs
,
static_libs
i shared_libs
w
Android.bp
i do LOCAL_HEADER_LIBRARIES
,
LOCAL_STATIC_LIBRARIES
i LOCAL_SHARED_LIBRARIES
w
Android.mk
.
LL-NDK
Biblioteki udostępnione LL-NDK to biblioteki udostępnione ze stabilnymi interfejsami ABI. Obie platformy
a moduły dostawców korzystają z tej samej i najnowszej implementacji. Dla każdej wartości
biblioteka współdzielona LL-NDK, cc_library
zawiera rozszerzenie
Właściwość llndk
z plikiem symboli:
cc_library { name: "libvndksupport", llndk: { symbol_file: "libvndksupport.map.txt", }, }
Plik symboli opisuje symbole widoczne dla modułów dostawców. Na przykład:
LIBVNDKSUPPORT { global: android_load_sphal_library; # llndk android_unload_sphal_library; # llndk local: *; };
Na podstawie pliku symboli system kompilacji generuje bibliotekę udostępnioną (stub) dla
modułów dostawcy, które łączą się z tymi bibliotekami,
Funkcja BOARD_VNDK_VERSION
jest włączona. Ten fragment zawiera symbol.
zasoby wspólne wyłącznie wtedy, gdy:
- Nie jest zdefiniowany w sekcji, która kończy się ciągiem
_PRIVATE
lub_PLATFORM
, - Nie zawiera tagu
#platform-only
i - Nie ma tagów
#introduce*
lub tag pasuje do cel.
VNDK
W plikach Android.bp
cc_library
cc_library_static
, cc_library_shared
i
Definicje modułów cc_library_headers
obsługują trzy powiązane z VNDK
usługi: vendor_available
, vndk.enabled
i
vndk.support_system_process
.
Jeśli vendor_available
lub vndk.enabled
to
true
, mogą być dostępne 2 warianty (główny i dostawca)
stworzona przez nas. Wariant podstawowy powinien być traktowany jako moduł platformy, a dostawca
powinna być traktowana jako moduł dostawcy. Jeśli niektóre moduły platformy zależą
w tym module powstaje
główny wariant. Jeśli niektóre moduły dostawcy
zależy od tego modułu, powstanie wariant dostawcy. System kompilacji wymusza stosowanie
te testy zależności:
- Główny wariant działa zawsze tylko w ramach platformy i jest niedostępny dla dostawcy modułów.
- Wariant dostawcy jest zawsze niedostępny dla modułów platformy.
- Wszystkie zależności wariantu dostawcy określone w
header_libs
,static_libs
lubshared_libs
musi mieć wartośćllndk_library
lub moduł zvendor_available
lubvndk.enabled
. - Jeśli
vendor_available
totrue
, wariant dostawcy jest dostępny dla wszystkich modułów dostawcy. - Jeśli
vendor_available
tofalse
, wariant dostawcy jest dostępny tylko dla innych modułów VNDK lub VNDK-SP (tj. modułów zvendor:true
nie może połączyć kontavendor_available:false
moduły).
Domyślna ścieżka instalacji dla: cc_library
lub
Wartość cc_library_shared
jest określana na podstawie tych reguł:
- Wariant podstawowy jest zainstalowany w:
/system/lib[64]
. - Ścieżka instalacji wariantu dostawcy może się różnić:
- Jeśli
vndk.enabled
tofalse
, wariant dostawcy jest zainstalowany w:/vendor/lib[64]
. - Jeśli
vndk.enabled
totrue
, wariant dostawcy jest zainstalowany w programie VNDK APEX(com.android.vndk.v${VER}
).
- Jeśli
W tej tabeli podano, jak system kompilacji obsługuje warianty dostawców:
opcja_dostępna_do_dostawcy | vndk włączono |
weryfikacja support_same_process |
Opisy wariantów dostawców |
---|---|---|---|
true |
false |
false |
Wersje dostawcy są dostępne WYŁĄCZNIE. Biblioteki udostępnione
zainstalowano w /vendor/lib[64] . |
true |
Nieprawidłowa (błąd kompilacji) | ||
true |
false |
Wersje dostawcy to VNDK. Biblioteki udostępnione zostały zainstalowane do VNDK APEX. | |
true |
Warianty dostawcy to VNDK-SP. Biblioteki udostępnione zainstalowano w VNDK APEX. | ||
|
|
|
Brak wersji dostawcy. Ten moduł jest TYLKO FWK. |
true |
Nieprawidłowa (błąd kompilacji) | ||
true |
false |
Warianty dostawcy to VNDK-Private. Biblioteki udostępnione zainstalowano w VNDK APEX. Nie mogą to być używane bezpośrednio przez moduły dostawców. | |
true |
Warianty dostawcy to VNDK-SP-Private. Biblioteki udostępnione zainstalowano w VNDK APEX. Nie mogą to być używane bezpośrednio przez moduły dostawców. |
Rozszerzenia VNDK
Rozszerzenia VNDK to udostępnione biblioteki VNDK z dodatkowymi interfejsami API. Rozszerzenia są
zainstalowana w systemie /vendor/lib[64]/vndk[-sp]
(bez sufiksu wersji)
i zastępować pierwotne biblioteki udostępnione VNDK w czasie działania.
Zdefiniuj rozszerzenia VNDK
W Androidzie 9 i nowszych Android.bp
natywnie obsługuje VNDK
rozszerzeń. Aby utworzyć rozszerzenie VNDK, zdefiniuj kolejny moduł z użyciem atrybutu
vendor:true
i usługa extends
:
cc_library { name: "libvndk", vendor_available: true, vndk: { enabled: true, }, } cc_library { name: "libvndk_ext", vendor: true, vndk: { enabled: true, extends: "libvndk", }, }
Moduł obejmujący vendor:true
, vndk.enabled:true
i
Właściwości extends
definiują rozszerzenie VNDK:
- Właściwość
extends
musi określać podstawową bibliotekę udostępnianą VNDK nazwa (lub nazwa biblioteki współdzielonej VNDK-SP). - Rozszerzenia VNDK (lub rozszerzenia VNDK-SP) mają nazwę odpowiadającą modułowi podstawowego
nazw, z których pochodzą. Na przykład wyjściowy plik binarny typu
libvndk_ext
ma wartośćlibvndk.so
zamiastlibvndk_ext.so
- Rozszerzenia VNDK są instalowane w systemie
/vendor/lib[64]/vndk
. - Rozszerzenia VNDK-SP są instalowane w
/vendor/lib[64]/vndk-sp
- Podstawowe biblioteki udostępnione muszą korzystać z obiektu
vndk.enabled:true
ivendor_available:true
.
Rozszerzenie VNDK-SP musi pochodzić z biblioteki współdzielonej VNDK-SP
(vndk.support_system_process
musi być równe):
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, }, }
Rozszerzenia VNDK (lub rozszerzenia VNDK-SP) mogą być zależne od udostępnianego przez innego dostawcę. biblioteki:
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, }
Używanie rozszerzeń VNDK
Jeśli moduł dostawcy zależy od dodatkowych interfejsów API zdefiniowanych przez rozszerzenia VNDK,
musi zawierać nazwę rozszerzenia VNDK w swoim
Właściwość 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", ], }
Jeśli moduł dostawcy jest oparty na rozszerzeniach VNDK, te rozszerzenia VNDK są
zainstalowano automatycznie w aplikacji /vendor/lib[64]/vndk[-sp]
. Jeśli moduł
nie zależy już od rozszerzenia VNDK, dodaj czysty krok do
CleanSpec.mk
, aby usunąć bibliotekę udostępnioną. Na przykład:
$(call add-clean-step, rm -rf $(TARGET_OUT_VENDOR)/lib/libvndk.so)
Kompilacja warunkowa
Ta sekcja wyjaśnia, jak radzić sobie z niewielkimi różnicami (np. dodanie cechy lub usunięcie jej z jednego z wariantów) pomiędzy 3 biblioteki udostępnione VNDK:
- Wariant podstawowy (np.
/system/lib[64]/libexample.so
) - Wariant dostawcy (np.
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so
) - Rozszerzenie VNDK (np.
/vendor/lib[64]/vndk[-sp]/libexample.so
)
Flagi warunkowego kompilatora
System kompilacji Androida definiuje __ANDROID_VNDK__
dla dostawcy
wersji i rozszerzeń VNDK. Możesz chronić kod
z zabezpieczeniami przed procesorem C:
void all() { } #if !defined(__ANDROID_VNDK__) void framework_only() { } #endif #if defined(__ANDROID_VNDK__) void vndk_only() { } #endif
Oprócz __ANDROID_VNDK__
, inne cflags
lub
cppflags
można określić w Android.bp
.
cflags
lub cppflags
określone w
Wartość target.vendor
odnosi się tylko do wariantu dostawcy.
Na przykład Android.bp
określa
libexample
i 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", ], }
A to jest kod strony 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
Zgodnie z tymi 2 plikami system kompilacji generuje biblioteki udostępnione z tymi wyeksportowanymi symbolami:
Ścieżka instalacji | Wyeksportowane 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 |
Wymagania dotyczące eksportowanych symboli
Narzędzie do sprawdzania ABI VNDK
porównuje interfejs ABI wariantów VNDK innych dostawców oraz
Rozszerzenia VNDK do zrzutów ABI pliku referencyjnego
prebuilts/abi-dumps/vndk
.
- Symbole eksportowane przez wersje dostawców VNDK (np.
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so
) musi być identyczny do (nie do nadzbiorów) symboli zdefiniowanych na zrzutach ABI. - symbole eksportowane przez rozszerzenia VNDK (np.
/vendor/lib[64]/vndk/libexample.so
) muszą być elementami nadrzędnymi elementu zdefiniowanych na zrzutach ABI.
Jeśli nie są zgodne wersje dostawcy VNDK lub rozszerzenia VNDK powyższe wymagania, mechanizm sprawdzania VNDK ABI generuje błędy kompilacji i zatrzymuje tworzyć.
Wyklucz pliki źródłowe lub biblioteki udostępnione z wariantów dostawcy
Aby wykluczyć pliki źródłowe z wariantu dostawcy, dodaj je do
exclude_srcs
. Aby biblioteki udostępnione były
nie są powiązane z wariantem dostawcy, dodaj te biblioteki do
exclude_shared_libs
. Na przykład:
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"], }, }, }
W tym przykładzie jest to podstawowy wariant słowa kluczowego libexample_cond_exclude
zawiera kod z witryn fwk.c
oraz both.c
i zależy
w bibliotekach udostępnionych libfwk_only
i libboth
.
wariant dostawcy atrybutu libexample_cond_exclude
zawiera tylko kod
z both.c
, ponieważ fwk.c
jest wykluczone przez regułę
właściwość exclude_srcs
. Zależy to tylko od zasobów wspólnych.
libboth
, ponieważ lokalizacja libfwk_only
jest wykluczona przez regułę
Usługa exclude_shared_libs
.
Eksportuj nagłówki z rozszerzeń VNDK
Rozszerzenie VNDK może dodawać nowe klasy lub nowe funkcje do udostępnionego VNDK bibliotece. Zalecamy zachowanie tych deklaracji w niezależnych nagłówkach. i unikaj zmiany istniejących nagłówków.
Na przykład nowy plik nagłówka
Utworzono include-ext/example/ext/feature_name.h
dla VNDK
rozszerzenie libexample_ext
:
- Android.bp
- include-ext/example/ext/nazwa_funkcji.h
- uwzględniaj/przyklad/przyklad.h
- src/example.c
- src/ext/nazwa_funkcji.c
W tych Android.bp
libexample
eksportów
tylko include
, a libexample_ext
eksportuje zarówno
include
i include-ext
. Dzięki temu masz pewność,
feature_name.h
nie zostanie błędnie uwzględniony przez użytkowników usługi
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", }, }
Jeśli nie można podzielić rozszerzeń na niezależne pliki nagłówka,
możesz też dodać #ifdef
zabezpieczeń. Upewnij się jednak, że wszystkie
Użytkownicy rozszerzenia VNDK dodają flagi definicji. Możesz zdefiniować
cc_defaults
, aby dodać flagi do zbioru danych cflags
i link
biblioteki udostępnione w bibliotece shared_libs
.
Aby na przykład dodać nową funkcję składową Example2::get_b()
do
rozszerzenie VNDK libexample2_ext
, musisz zmodyfikować istniejące
plik nagłówka i dodaj zabezpieczenie #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_
Obecny stan elementu cc_defaults
o nazwie libexample2_ext_defaults
:
zdefiniowane dla użytkowników aplikacji 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", ], }
Użytkownicy libexample2_ext
mogą po prostu dodać
libexample2_ext_defaults
w: defaults
usługa:
cc_binary { name: "example2_user_executable", defaults: ["libexample2_ext_defaults"], vendor: true, }
Pakiety produktów
W systemie kompilacji Androida zmienna PRODUCT_PACKAGES
określa pliki wykonywalne, biblioteki udostępnione lub pakiety, które powinny zostać
zainstalowanej na urządzeniu. Zależności przejściowe określonego
moduły są wbudowane bezpośrednio w urządzenie.
Jeśli włączona jest funkcja BOARD_VNDK_VERSION
, moduły z atrybutem
vendor_available
lub vndk.enabled
zyskaj wyjątkowe nagrody
terapii. Jeśli moduł struktury bazuje na module z atrybutem
vendor_available
lub vndk.enabled
(wersja podstawowa)
jest dołączony do przejściowego zestawu instalacji. Jeśli moduł dostawcy
zależy od modułu z atrybutem vendor_available
, wariant dostawcy to
zawarte w przechodnim zestawie instalacyjnym. Jednak wersje modułów oferowane przez dostawców
z rozszerzeniem vndk.enabled
są instalowane niezależnie od tego, czy są używane przez moduły dostawców.
Gdy zależności są niewidoczne dla systemu kompilacji (np. biblioteki udostępnione
które można otwierać za pomocą dlopen()
w czasie działania), określ
nazwy modułów w programie PRODUCT_PACKAGES
, aby je zainstalować
bezpośrednio.
Jeśli moduł ma vendor_available
lub vndk.enabled
,
nazwa modułu to jej podstawowa wersja. Aby wprost określić parametr
wariant dostawcy w: PRODUCT_PACKAGES
, dołącz .vendor
do nazwy modułu. Na przykład:
cc_library { name: "libexample", srcs: ["example.c"], vendor_available: true, }
W tym przykładzie libexample
to skrót od
/system/lib[64]/libexample.so
i libexample.vendor
oznacza /vendor/lib[64]/libexample.so
. Aby zainstalować
/vendor/lib[64]/libexample.so
, dodaj libexample.vendor
do PRODUCT_PACKAGES
:
PRODUCT_PACKAGES += libexample.vendor