Obsługa systemu kompilacji VNDK

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:

libexampleVendor_available:true i vndk.enabled:true

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}

VNDK APEX

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 z vendor:true lub
  • moduł z funkcją vendor:true zależy od moduł inny niż llndk_library, który nie zawiera żadnego vendor:true ani vendor_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 lub shared_libs musi mieć wartość llndk_library lub moduł z vendor_available lub vndk.enabled.
  • Jeśli vendor_available to true, wariant dostawcy jest dostępny dla wszystkich modułów dostawcy.
  • Jeśli vendor_available to false, wariant dostawcy jest dostępny tylko dla innych modułów VNDK lub VNDK-SP (tj. modułów z vendor:true nie może połączyć konta vendor_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 to false, wariant dostawcy jest zainstalowany w: /vendor/lib[64].
    • Jeśli vndk.enabled to true, wariant dostawcy jest zainstalowany w programie VNDK APEX(com.android.vndk.v${VER}).

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.

false

false

false

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 zamiast libvndk_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 i vendor_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