Di Android 8.1 dan yang lebih tinggi, sistem build memiliki dukungan VNDK bawaan. Jika dukungan VNDK diaktifkan, sistem build akan memeriksa dependensi antar-modul, membuat varian khusus vendor untuk modul vendor, dan menginstal modul tersebut secara otomatis ke direktori yang ditentukan.
Contoh dukungan build VNDK
Dalam contoh ini, definisi modul Android.bp menentukan
library bernama libexample. Properti vendor_available
menunjukkan bahwa modul framework dan modul vendor mungkin bergantung pada
libexample:
Gambar 1. dukungan diaktifkan.
File yang dapat dieksekusi framework /system/bin/foo dan file yang dapat dieksekusi vendor /vendor/bin/bar bergantung pada libexample dan memiliki libexample di properti shared_libs-nya.
Jika libexample digunakan oleh modul framework dan modul vendor, dua varian libexample akan dibangun. Varian inti
(diberi nama sesuai dengan libexample) digunakan oleh modul framework dan
varian vendor (diberi nama sesuai dengan libexample.vendor) digunakan oleh modul
vendor. Kedua varian diinstal ke direktori yang berbeda:
- Varian inti diinstal ke
/system/lib[64]/libexample.so. - Varian vendor diinstal ke VNDK APEX karena
vndk.enabledadalahtrue.
Untuk mengetahui detail selengkapnya, lihat Definisi modul.
Mengonfigurasi dukungan build
Untuk mengaktifkan dukungan sistem build penuh untuk perangkat produk, tambahkan
BOARD_VNDK_VERSION ke BoardConfig.mk:
BOARD_VNDK_VERSION := current
Setelan ini memiliki efek global: Jika ditentukan dalam
BoardConfig.mk, semua modul akan diperiksa. Karena tidak ada mekanisme untuk memasukkan modul yang bermasalah ke daftar yang tidak diizinkan atau daftar yang diizinkan, Anda harus menghapus semua dependensi yang tidak diperlukan sebelum menambahkan BOARD_VNDK_VERSION. Anda
dapat menguji dan mengompilasi modul dengan menyetel BOARD_VNDK_VERSION di
variabel lingkungan Anda:
$ BOARD_VNDK_VERSION=current m module_name.vendor
Jika BOARD_VNDK_VERSION diaktifkan, beberapa jalur penelusuran header global default akan dihapus. Ini mencakup:
frameworks/av/includeframeworks/native/includeframeworks/native/opengl/includehardware/libhardware/includehardware/libhardware_legacy/includehardware/ril/includelibnativehelper/includelibnativehelper/include_deprecatedsystem/core/includesystem/media/audio/include
Jika modul bergantung pada header dari direktori ini, Anda harus menentukan
(secara eksplisit) dependensi dengan header_libs,
static_libs, dan/atau shared_libs.
APEX VNDK
Di Android 10 dan yang lebih lama, modul dengan vndk.enabled diinstal di
/system/lib[64]/vndk[-sp]-${VER}. Di Android 11 dan yang lebih tinggi,
library VNDK dikemas dalam format APEX dan nama VNDK APEX adalah
com.android.vndk.v${VER}. Bergantung pada konfigurasi perangkat,
APEX VNDK diratakan atau tidak diratakan dan tersedia dari jalur kanonis
/apex/com.android.vndk.v${VER}.

Gambar 2. APEX VNDK.
Definisi modul
Untuk membuat Android dengan BOARD_VNDK_VERSION, Anda harus merevisi
definisi modul di Android.mk atau
Android.bp. Bagian ini menjelaskan berbagai jenis definisi modul, beberapa properti modul terkait VNDK, dan pemeriksaan dependensi yang diterapkan dalam sistem build.
Modul vendor
Modul vendor adalah file executable atau library bersama khusus vendor yang harus diinstal ke partisi vendor. Dalam file Android.bp,
modul vendor harus menetapkan properti vendor atau eksklusif ke true.
Dalam file Android.mk, modul vendor harus menetapkan
LOCAL_VENDOR_MODULE atau LOCAL_PROPRIETARY_MODULE ke
true.
Jika BOARD_VNDK_VERSION ditentukan, sistem build tidak mengizinkan
dependensi antara modul vendor dan modul framework, serta akan memunculkan error jika:
- modul tanpa
vendor:truebergantung pada modul denganvendor:true, atau - modul dengan
vendor:truebergantung pada modul non-llndk_libraryyang tidak memilikivendor:truemaupunvendor_available:true.
Pemeriksaan dependensi berlaku untuk header_libs,
static_libs, dan shared_libs di
Android.bp, serta untuk LOCAL_HEADER_LIBRARIES,
LOCAL_STATIC_LIBRARIES, dan LOCAL_SHARED_LIBRARIES di
Android.mk.
LL-NDK
Library bersama LL-NDK adalah library bersama dengan ABI yang stabil. Modul framework dan vendor memiliki implementasi yang sama dan terbaru. Untuk setiap
library bersama LL-NDK, cc_library berisi
properti llndk dengan file simbol:
cc_library { name: "libvndksupport", llndk: { symbol_file: "libvndksupport.map.txt", }, }
File simbol menjelaskan simbol yang terlihat oleh modul vendor. Contoh:
LIBVNDKSUPPORT { global: android_load_sphal_library; # llndk android_unload_sphal_library; # llndk local: *; };
Berdasarkan file simbol, sistem build menghasilkan library bersama stub untuk
modul vendor, yang ditautkan dengan library ini saat
BOARD_VNDK_VERSION diaktifkan. Simbol disertakan dalam stub
library bersama hanya jika:
- Tidak ditentukan di bagian yang diakhiri dengan
_PRIVATEatau_PLATFORM, - Tidak memiliki tag
#platform-only, dan - Tidak memiliki tag
#introduce*atau tag cocok dengan target.
VNDK
Dalam file Android.bp, definisi modul cc_library,
cc_library_static, cc_library_shared, dan
cc_library_headers mendukung tiga properti terkait VNDK: vendor_available, vndk.enabled, dan
vndk.support_system_process.
Jika vendor_available atau vndk.enabled adalah
true, dua varian (core dan vendor) dapat
dibuat. Varian inti harus diperlakukan sebagai modul framework dan varian vendor harus diperlakukan sebagai modul vendor. Jika beberapa modul framework bergantung pada modul ini, varian inti akan dibuat. Jika beberapa modul vendor bergantung pada modul ini, varian vendor akan dibuat. Sistem build menerapkan
pemeriksaan dependensi berikut:
- Varian inti selalu hanya framework dan tidak dapat diakses oleh modul vendor
- Varian vendor selalu tidak dapat diakses oleh modul framework.
- Semua dependensi varian vendor, yang ditentukan dalam
header_libs,static_libs, dan/ataushared_libs, harus berupallndk_libraryatau modul denganvendor_availableatauvndk.enabled. - Jika
vendor_availableadalahtrue, varian vendor dapat diakses oleh semua modul vendor. - Jika
vendor_availableadalahfalse, varian vendor hanya dapat diakses oleh modul VNDK atau VNDK-SP lainnya (yaitu, modul denganvendor:truetidak dapat menautkan modulvendor_available:false).
Jalur penginstalan default untuk cc_library atau
cc_library_shared ditentukan oleh aturan berikut:
- Varian inti diinstal ke
/system/lib[64]. - Jalur penginstalan varian vendor dapat bervariasi:
- Jika
vndk.enabledadalahfalse, varian vendor diinstal ke/vendor/lib[64]. - Jika
vndk.enabledadalahtrue, varian vendor diinstal ke VNDK APEX(com.android.vndk.v${VER}).
- Jika
Tabel di bawah merangkum cara sistem build menangani varian vendor:
| vendor_available | vndk enabled |
vndk support_system_process |
Deskripsi varian vendor |
|---|---|---|---|
true |
false |
false |
Varian vendor adalah KHUSUS-VND. Library bersama diinstal ke /vendor/lib[64]. |
true |
Tidak valid (Error build) | ||
true |
false |
Varian vendor adalah VNDK. Library bersama diinstal ke APEX VNDK. | |
true |
Varian vendor adalah VNDK-SP. Library bersama diinstal ke APEX VNDK. | ||
|
|
|
Tidak ada varian vendor. Modul ini adalah FWK-ONLY. |
true |
Tidak valid (Error build) | ||
true |
false |
Varian vendor adalah VNDK-Private. Library bersama diinstal ke APEX VNDK. Ini tidak boleh digunakan langsung oleh modul vendor. | |
true |
Varian vendor adalah VNDK-SP-Private. Library bersama diinstal ke APEX VNDK. Ini tidak boleh digunakan langsung oleh modul vendor. |
Ekstensi VNDK
Ekstensi VNDK adalah library bersama VNDK dengan API tambahan. Ekstensi diinstal ke /vendor/lib[64]/vndk[-sp] (tanpa sufiks versi) dan menggantikan library bersama VNDK asli saat runtime.
Menentukan ekstensi VNDK
Di Android 9 dan yang lebih baru, Android.bp secara native mendukung ekstensi VNDK. Untuk membuat ekstensi VNDK, tentukan modul lain dengan
properti vendor:true dan extends:
cc_library { name: "libvndk", vendor_available: true, vndk: { enabled: true, }, } cc_library { name: "libvndk_ext", vendor: true, vndk: { enabled: true, extends: "libvndk", }, }
Modul dengan properti vendor:true, vndk.enabled:true, dan
extends menentukan ekstensi VNDK:
- Properti
extendsharus menentukan nama library bersama VNDK dasar (atau nama library bersama VNDK-SP). - Ekstensi VNDK (atau ekstensi VNDK-SP) diberi nama sesuai dengan nama modul dasar yang diperluasnya. Misalnya, biner output
libvndk_extadalahlibvndk.so, bukanlibvndk_ext.so. - Ekstensi VNDK diinstal ke
/vendor/lib[64]/vndk. - Ekstensi VNDK-SP diinstal ke
/vendor/lib[64]/vndk-sp. - Library bersama dasar harus memiliki
vndk.enabled:truedanvendor_available:true.
Ekstensi VNDK-SP harus diperluas dari library bersama VNDK-SP
(vndk.support_system_process harus sama):
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, }, }
Ekstensi VNDK (atau ekstensi VNDK-SP) dapat bergantung pada library bersama vendor lain:
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, }
Menggunakan ekstensi VNDK
Jika modul vendor bergantung pada API tambahan yang ditentukan oleh ekstensi VNDK, modul
harus menentukan nama ekstensi VNDK di properti
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", ], }
Jika modul vendor bergantung pada ekstensi VNDK, ekstensi VNDK tersebut akan
diinstal ke /vendor/lib[64]/vndk[-sp] secara otomatis. Jika modul tidak lagi bergantung pada ekstensi VNDK, tambahkan langkah pembersihan ke CleanSpec.mk untuk menghapus library bersama. Contoh:
$(call add-clean-step, rm -rf $(TARGET_OUT_VENDOR)/lib/libvndk.so)
Kompilasi bersyarat
Bagian ini menjelaskan cara menangani perbedaan kecil (misalnya, menambahkan atau menghapus fitur dari salah satu varian) antara tiga library bersama VNDK berikut:
- Varian inti (misalnya,
/system/lib[64]/libexample.so) - Varian vendor (misalnya
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so) - Ekstensi VNDK (misalnya,
/vendor/lib[64]/vndk[-sp]/libexample.so)
Flag compiler bersyarat
Sistem build Android menentukan __ANDROID_VNDK__ untuk varian vendor dan ekstensi VNDK secara default. Anda dapat melindungi kode
dengan pelindung praprosesor C:
void all() { }
#if !defined(__ANDROID_VNDK__)
void framework_only() { }
#endif
#if defined(__ANDROID_VNDK__)
void vndk_only() { }
#endif
Selain __ANDROID_VNDK__, cflags atau
cppflags yang berbeda dapat ditentukan di Android.bp. cflags atau cppflags yang ditentukan di target.vendor khusus untuk varian vendor.
Misalnya, Android.bp berikut menentukan
libexample dan 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", ], }
Berikut adalah listingan kode 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() { }
#endifMenurut kedua file ini, sistem build menghasilkan library bersama dengan simbol yang diekspor berikut:
| Jalur penginstalan | Simbol yang diekspor |
|---|---|
/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 |
Persyaratan pada simbol yang diekspor
Pemeriksa ABI VNDK
membandingkan ABI varian vendor VNDK dan
ekstensi VNDK dengan dump ABI referensi di
prebuilts/abi-dumps/vndk.
- Simbol yang diekspor oleh varian vendor VNDK (misalnya,
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so) harus identik dengan (bukan superset dari) simbol yang ditentukan dalam dump ABI. - Simbol yang diekspor oleh ekstensi VNDK (misalnya,
/vendor/lib[64]/vndk/libexample.so) harus berupa superset dari simbol yang ditentukan dalam dump ABI.
Jika varian vendor VNDK atau ekstensi VNDK gagal mengikuti persyaratan di atas, pemeriksa ABI VNDK akan memunculkan error build dan menghentikan build.
Mengecualikan file sumber atau library bersama dari varian vendor
Untuk mengecualikan file sumber dari varian vendor, tambahkan file tersebut ke
properti exclude_srcs. Demikian pula, untuk memastikan library bersama tidak ditautkan dengan varian vendor, tambahkan library tersebut ke properti exclude_shared_libs. Contoh:
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"], }, }, }
Dalam contoh ini, varian inti libexample_cond_exclude
mencakup kode dari fwk.c dan both.c serta bergantung
pada library bersama libfwk_only dan libboth. Varian vendor libexample_cond_exclude hanya menyertakan kode dari both.c karena fwk.c dikecualikan oleh properti exclude_srcs. Demikian pula, library ini hanya bergantung pada library bersama
libboth karena libfwk_only dikecualikan oleh properti
exclude_shared_libs.
Mengekspor header dari ekstensi VNDK
Ekstensi VNDK dapat menambahkan class baru atau fungsi baru ke library bersama VNDK. Sebaiknya simpan deklarasi tersebut di header terpisah dan jangan mengubah header yang ada.
Misalnya, file header baru
include-ext/example/ext/feature_name.h dibuat untuk ekstensi
VNDK libexample_ext:
- Android.bp
- include-ext/example/ext/feature_name.h
- include/example/example.h
- src/example.c
- src/ext/feature_name.c
Pada Android.bp berikut, libexample hanya mengekspor
include, sedangkan libexample_ext mengekspor
include dan include-ext. Hal ini memastikan bahwa
feature_name.h tidak akan disertakan secara keliru oleh pengguna
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", }, }
Jika pemisahan ekstensi ke file header independen tidak memungkinkan, alternatifnya adalah menambahkan pemeriksaan #ifdef. Namun, pastikan semua
pengguna ekstensi VNDK menambahkan tanda define. Anda dapat menentukan
cc_defaults untuk menambahkan flag define ke cflags dan menautkan
library bersama dengan shared_libs.
Misalnya, untuk menambahkan fungsi anggota baru Example2::get_b() ke
ekstensi VNDK libexample2_ext, Anda harus mengubah file
header yang ada dan menambahkan penjaga #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_
cc_defaults bernama libexample2_ext_defaults ditentukan untuk pengguna 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", ], }
Pengguna libexample2_ext dapat menyertakan
libexample2_ext_defaults di properti defaults
mereka:
cc_binary {
name: "example2_user_executable",
defaults: ["libexample2_ext_defaults"],
vendor: true,
}Paket produk
Dalam sistem build Android, variabel PRODUCT_PACKAGES
menentukan file yang dapat dieksekusi, library bersama, atau paket yang harus
diinstal ke perangkat. Dependensi transitif dari modul yang ditentukan
juga diinstal secara implisit ke perangkat.
Jika BOARD_VNDK_VERSION diaktifkan, modul dengan
vendor_available atau vndk.enabled akan mendapatkan
perlakuan khusus. Jika modul framework bergantung pada modul dengan
vendor_available atau vndk.enabled, varian inti
akan disertakan dalam set penginstalan transitif. Jika modul vendor
bergantung pada modul dengan vendor_available, varian vendor akan
disertakan dalam set penginstalan transitif. Namun, varian modul vendor
dengan vndk.enabled diinstal, terlepas dari apakah digunakan oleh modul vendor atau tidak.
Jika dependensi tidak terlihat oleh sistem build (misalnya, library bersama
yang dapat dibuka dengan dlopen() saat runtime), Anda harus menentukan
nama modul di PRODUCT_PACKAGES untuk menginstal modul tersebut
secara eksplisit.
Jika modul memiliki vendor_available atau vndk.enabled,
nama modul mewakili varian intinya. Untuk menentukan varian vendor secara eksplisit di PRODUCT_PACKAGES, tambahkan akhiran .vendor ke nama modul. Contoh:
cc_library { name: "libexample", srcs: ["example.c"], vendor_available: true, }
Dalam contoh ini, libexample adalah
/system/lib[64]/libexample.so dan libexample.vendor
adalah /vendor/lib[64]/libexample.so. Untuk menginstal
/vendor/lib[64]/libexample.so, tambahkan libexample.vendor
ke PRODUCT_PACKAGES:
PRODUCT_PACKAGES += libexample.vendor