Di Android 8.1 dan yang lebih tinggi, sistem build memiliki dukungan VNDK bawaan. Saat dukungan VNDK diaktifkan, sistem build akan memeriksa dependensi antar modul, mem-build varian khusus vendor untuk modul vendor, dan otomatis menginstal modul tersebut ke direktori yang ditetapkan.
Contoh dukungan build VNDK
Dalam contoh ini, definisi modul Android.bp
menentukan
library bernama libexample
. Properti vendor_available
menunjukkan modul framework dan modul vendor dapat bergantung pada
libexample
:
Gambar 1. diaktifkan.
/system/bin/foo
yang dapat dieksekusi framework dan /vendor/bin/bar
yang dapat dieksekusi vendor bergantung pada libexample
dan
memiliki libexample
dalam properti shared_libs
-nya.
Jika libexample
digunakan oleh modul framework dan modul
vendor, dua varian libexample
akan di-build. Varian inti
(dinamai setelah libexample
) digunakan oleh modul framework dan
varian vendor (dinamai setelah libexample.vendor
) digunakan oleh modul
vendor. Kedua varian diinstal ke dalam direktori yang berbeda:
- Varian inti diinstal ke
/system/lib[64]/libexample.so
. - Varian vendor diinstal ke VNDK APEX karena
vndk.enabled
adalahtrue
.
Untuk detail selengkapnya, lihat Definisi modul.
Mengonfigurasi dukungan build
Untuk mengaktifkan dukungan sistem build penuh bagi perangkat produk, tambahkan
BOARD_VNDK_VERSION
ke BoardConfig.mk
:
BOARD_VNDK_VERSION := current
Setelan ini memiliki efek global: Jika ditentukan di
BoardConfig.mk
, semua modul akan diperiksa. Karena tidak ada mekanisme untuk memblokir atau mengizinkan modul yang bermasalah, Anda harus membersihkan semua dependensi yang tidak diperlukan sebelum menambahkan BOARD_VNDK_VERSION
. Anda
dapat menguji dan mengompilasi modul dengan menetapkan BOARD_VNDK_VERSION
di
variabel lingkungan:
$ 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/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
Jika modul bergantung pada header dari direktori ini, Anda harus menentukan
(secara eksplisit) dependensi dengan header_libs
,
static_libs
, dan/atau shared_libs
.
VNDK APEX
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,
VNDK APEX diratakan atau tidak diratakan dan tersedia dari jalur kanonis
/apex/com.android.vndk.v${VER}
.
Gambar 2. VNDK APEX.
Definisi modul
Untuk mem-build 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 library yang dapat dieksekusi khusus vendor atau library bersama yang
harus diinstal ke dalam partisi vendor. Dalam file Android.bp
,
modul vendor harus menetapkan properti vendor atau properti 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 menampilkan error jika:
- modul tanpa
vendor:true
bergantung pada modul denganvendor:true
, atau - modul dengan
vendor:true
bergantung pada modul non-llndk_library
yang tidak memilikivendor:true
atauvendor_available:true
.
Pemeriksaan dependensi berlaku untuk header_libs
, static_libs
, dan shared_libs
dalam Android.bp
, serta untuk LOCAL_HEADER_LIBRARIES
, LOCAL_STATIC_LIBRARIES
, dan LOCAL_SHARED_LIBRARIES
dalam 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 akan menghasilkan library bersama stub untuk
modul vendor, yang ditautkan dengan library ini saat
BOARD_VNDK_VERSION
diaktifkan. Simbol disertakan dalam library bersama
stub hanya jika:
- Tidak ditentukan di bagian yang diakhiri dengan
_PRIVATE
atau_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 di-build. Jika beberapa modul vendor
bergantung pada modul ini, varian vendor akan di-build. Sistem build menerapkan
pemeriksaan dependensi berikut:
- Varian inti selalu khusus 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_library
atau modul denganvendor_available
atauvndk.enabled
. - Jika
vendor_available
adalahtrue
, varian vendor dapat diakses oleh semua modul vendor. - Jika
vendor_available
adalahfalse
, varian vendor hanya dapat diakses oleh modul VNDK atau VNDK-SP lainnya (yaitu, modul denganvendor:true
tidak 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.enabled
adalahfalse
, varian vendor akan diinstal ke/vendor/lib[64]
. - Jika
vndk.enabled
adalahtrue
, varian vendor akan 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_same_process |
Deskripsi varian vendor |
---|---|---|---|
true |
false |
false |
Varian vendor adalah HANYA VND. Library bersama
diinstal ke /vendor/lib[64] . |
true |
Tidak valid (Error build) | ||
true |
false |
Varian vendor adalah VNDK. Library bersama diinstal ke VNDK APEX. | |
true |
Varian vendor adalah VNDK-SP. Library bersama diinstal ke VNDK APEX. | ||
|
|
|
Tidak ada varian vendor. Modul ini adalah HANYA FWK. |
true |
Tidak valid (Error build) | ||
true |
false |
Varian vendor adalah VNDK-Private. Library bersama diinstal ke VNDK APEX. Solusi ini tidak boleh langsung digunakan oleh modul vendor. | |
true |
Varian vendor adalah VNDK-SP-Private. Library bersama diinstal ke VNDK APEX. 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 akhiran versi)
dan mengganti library bersama VNDK asli saat runtime.
Menentukan ekstensi VNDK
Di Android 9 dan yang lebih baru, Android.bp
secara native mendukung ekstensi
VNDK. Untuk mem-build 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
extends
harus menentukan nama library bersama VNDK dasar (atau nama library bersama VNDK-SP). - Ekstensi VNDK (atau ekstensi VNDK-SP) diberi nama berdasarkan nama modul dasar
tempat ekstensi tersebut berasal. Misalnya, biner output
libvndk_ext
adalahlibvndk.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:true
danvendor_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 dalam
properti shared_libs
-nya:
// 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 penjaga preprocessor 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 dalam
target.vendor
bersifat 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", ], }
Dan ini 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() { } #endif
Menurut 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) simbol yang ditentukan dalam dump ABI. - Simbol yang diekspor oleh ekstensi VNDK (misalnya,
/vendor/lib[64]/vndk/libexample.so
) harus berupa superset 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
menyertakan 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, kode 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 dalam header independen dan hindari 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
Dalam Android.bp
berikut, libexample
hanya mengekspor
include
, sedangkan libexample_ext
mengekspor
include
dan include-ext
. Hal ini memastikan
feature_name.h
tidak akan salah disertakan 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 memisahkan ekstensi ke file header independen tidak memungkinkan, alternatifnya adalah menambahkan penjaga #ifdef
. Namun, pastikan semua
pengguna ekstensi VNDK menambahkan flag definisi. Anda dapat menentukan
cc_defaults
untuk menambahkan flag yang ditentukan 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 guard #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
cukup menyertakan
libexample2_ext_defaults
dalam 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 dalam perangkat. Dependensi transitif dari modul yang ditentukan
juga diinstal secara implisit ke dalam 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 kumpulan penginstalan transitif. Jika modul vendor
bergantung pada modul dengan vendor_available
, varian vendor
akan disertakan dalam kumpulan penginstalan transitif. Namun, varian vendor modul
dengan vndk.enabled
diinstal, terlepas dari apakah modul tersebut digunakan oleh modul vendor atau tidak.
Jika dependensi tidak terlihat oleh sistem build (misalnya, library bersama
yang dapat dibuka dengan dlopen()
dalam 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 akan 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 singkatan dari
/system/lib[64]/libexample.so
dan libexample.vendor
adalah singkatan dari /vendor/lib[64]/libexample.so
. Untuk menginstal
/vendor/lib[64]/libexample.so
, tambahkan libexample.vendor
ke PRODUCT_PACKAGES
:
PRODUCT_PACKAGES += libexample.vendor