Di Android 8.1 dan lebih tinggi, sistem build memiliki dukungan VNDK bawaan. Ketika dukungan VNDK diaktifkan, sistem build memeriksa ketergantungan antar modul, membuat varian khusus vendor untuk modul vendor, dan secara otomatis menginstal modul tersebut ke direktori yang ditentukan.
Contoh dukungan pembuatan VNDK
Dalam contoh ini, definisi modul Android.bp
mendefinisikan perpustakaan bernama libexample
. Properti vendor_available
menunjukkan modul kerangka kerja dan modul vendor mungkin bergantung pada libexample
:
Baik kerangka kerja yang dapat dieksekusi /system/bin/foo
maupun vendor yang dapat dieksekusi /vendor/bin/bar
bergantung pada libexample
dan memiliki libexample
di properti shared_libs
nya.
Jika libexample
digunakan oleh modul kerangka kerja dan modul vendor, dua varian libexample
akan dibuat. Varian inti (dinamai libexample
) digunakan oleh modul kerangka kerja dan varian vendor (dinamai libexample.vendor
) digunakan oleh modul vendor. Kedua varian tersebut diinstal ke direktori 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 untuk perangkat produk, tambahkan BOARD_VNDK_VERSION
ke BoardConfig.mk
:
BOARD_VNDK_VERSION := current
Pengaturan ini memiliki efek global : Ketika ditentukan di BoardConfig.mk
, semua modul dicentang. Karena tidak ada mekanisme untuk memasukkan modul yang melanggar ke dalam daftar hitam atau daftar putih, Anda harus membersihkan semua dependensi yang tidak perlu sebelum menambahkan BOARD_VNDK_VERSION
. Anda dapat menguji dan mengkompilasi modul dengan mengatur BOARD_VNDK_VERSION
di variabel lingkungan Anda:
$ BOARD_VNDK_VERSION=current m module_name.vendor
Jika BOARD_VNDK_VERSION
diaktifkan, beberapa jalur pencarian header global default akan dihapus . Ini termasuk:
-
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 sebuah 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 rendah, modul dengan vndk.enabled
dipasang di /system/lib[64]/vndk[-sp]-${VER}
. Di Android 11 dan lebih tinggi, perpustakaan VNDK dikemas dalam format APEX dan nama VNDK APEX adalah com.android.vndk.v${VER}
. Tergantung pada konfigurasi perangkat, VNDK APEX dapat diratakan atau tidak dan tersedia dari jalur kanonik /apex/com.android.vndk.v${VER}
.
Definisi modul
Untuk membangun 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 ketergantungan yang diterapkan dalam sistem build.
Modul vendor
Modul vendor adalah executable atau pustaka bersama khusus vendor yang harus diinstal ke dalam partisi vendor. Dalam file Android.bp
, modul vendor harus menyetel properti vendor atau kepemilikan ke true
. Dalam file Android.mk
, modul vendor harus menyetel LOCAL_VENDOR_MODULE
atau LOCAL_PROPRIETARY_MODULE
ke true
.
Jika BOARD_VNDK_VERSION
ditentukan, sistem build tidak mengizinkan ketergantungan antara modul vendor dan modul kerangka kerja dan mengeluarkan kesalahan 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
maupunvendor_available:true
.
Pemeriksaan ketergantungan 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
Pustaka bersama LL-NDK adalah pustaka bersama dengan ABI stabil. Baik modul framework maupun vendor memiliki implementasi yang sama dan terbaru. Untuk setiap pustaka 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. Misalnya:
LIBVNDKSUPPORT { global: android_load_sphal_library; # llndk android_unload_sphal_library; # llndk local: *; };
Berdasarkan file simbol, sistem pembangunan menghasilkan pustaka bersama stub untuk modul vendor, yang tertaut dengan pustaka ini ketika BOARD_VNDK_VERSION
diaktifkan. Sebuah simbol disertakan dalam perpustakaan bersama rintisan hanya jika:
- Tidak ditentukan di bagian yang diakhiri dengan
_PRIVATE
atau_PLATFORM
, - Tidak memiliki tag
#platform-only
, dan - Tidak memiliki tag
#introduce*
atau tag sesuai 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 kerangka kerja dan varian vendor harus diperlakukan sebagai modul vendor. Jika beberapa modul kerangka kerja bergantung pada modul ini, varian inti akan dibuat. Jika beberapa modul vendor bergantung pada modul ini, varian vendor akan dibuat. Sistem build menerapkan pemeriksaan ketergantungan berikut:
- Varian inti selalu hanya kerangka kerja dan tidak dapat diakses oleh modul vendor.
- Varian vendor selalu tidak dapat diakses oleh modul kerangka kerja.
- 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
bernilaitrue
, 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 menghubungkan modulvendor_available:false
).
Jalur instalasi default untuk cc_library
atau cc_library_shared
ditentukan oleh aturan berikut:
- Varian inti diinstal ke
/system/lib[64]
. - Jalur instalasi varian vendor mungkin berbeda:
- Jika
vndk.enabled
adalahfalse
, varian vendor diinstal ke/vendor/lib[64]
. - Jika
vndk.enabled
adalahtrue
, varian vendor diinstal ke VNDK APEX(com.android.vndk.v${VER}
).
- Jika
Tabel di bawah ini merangkum cara sistem build menangani varian vendor:
vendor_tersedia | vndk diaktifkan | vndk dukungan_proses_sama | Deskripsi varian vendor |
---|---|---|---|
true | false | false | Varian vendor HANYA VND . Pustaka bersama dipasang ke /vendor/lib[64] . |
true | Tidak valid (Kesalahan pembuatan) | ||
true | false | Varian vendornya adalah VNDK . Pustaka bersama diinstal ke VNDK APEX. | |
true | Varian vendornya adalah VNDK-SP . Pustaka bersama diinstal ke VNDK APEX. | ||
| | | Tidak ada varian vendor. Modul ini HANYA FWK . |
true | Tidak valid (Kesalahan pembuatan) | ||
true | false | Varian vendornya adalah VNDK-Private . Pustaka bersama diinstal ke VNDK APEX. Ini tidak boleh digunakan secara langsung oleh modul vendor. | |
true | Varian vendornya adalah VNDK-SP-Private . Pustaka bersama diinstal ke VNDK APEX. Ini tidak boleh digunakan secara langsung oleh modul vendor. |
Ekstensi VNDK
Ekstensi VNDK adalah perpustakaan bersama VNDK dengan API tambahan. Ekstensi diinstal ke /vendor/lib[64]/vndk[-sp]
(tanpa akhiran versi) dan menimpa pustaka bersama VNDK asli saat runtime.
Mendefinisikan ekstensi VNDK
Di Android 9 dan lebih tinggi, Android.bp
secara asli mendukung ekstensi VNDK. Untuk membangun 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 vendor:true
, vndk.enabled:true
, dan extends
mendefinisikan ekstensi VNDK:
- Properti
extends
harus menentukan nama perpustakaan bersama VNDK dasar (atau nama perpustakaan bersama VNDK-SP). - Ekstensi VNDK (atau ekstensi VNDK-SP) diberi nama sesuai nama modul dasar yang diperluas. Misalnya, biner keluaran
libvndk_ext
adalahlibvndk.so
, bukanlibvndk_ext.so
. - Ekstensi VNDK dipasang ke
/vendor/lib[64]/vndk
. - Ekstensi VNDK-SP dipasang ke
/vendor/lib[64]/vndk-sp
. - Pustaka bersama dasar harus memiliki
vndk.enabled:true
danvendor_available:true
.
Ekstensi VNDK-SP harus diperluas dari pustaka 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) mungkin bergantung pada pustaka bersama vendor lainnya:
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
-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 diinstal ke /vendor/lib[64]/vndk[-sp]
secara otomatis. Jika modul tidak lagi bergantung pada ekstensi VNDK, tambahkan langkah bersih ke CleanSpec.mk
untuk menghapus pustaka bersama. Misalnya:
$(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 pustaka 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
)
Bendera kompiler bersyarat
Sistem build Android mendefinisikan __ANDROID_VNDK__
untuk varian vendor dan ekstensi VNDK secara default. Anda dapat menjaga kode dengan penjaga 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 mendefinisikan 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 daftar 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
Berdasarkan kedua file ini, sistem build menghasilkan pustaka bersama dengan simbol yang diekspor berikut:
Jalur instalasi | 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 pada 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 mengeluarkan kesalahan build dan menghentikan build.
Tidak termasuk file sumber atau pustaka bersama dari varian vendor
Untuk mengecualikan file sumber dari varian vendor, tambahkan file tersebut ke properti exclude_srcs
. Demikian pula, untuk memastikan pustaka bersama tidak tertaut dengan varian vendor, tambahkan pustaka tersebut ke properti exclude_shared_libs
. Misalnya:
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 pustaka bersama libfwk_only
dan libboth
. Varian vendor dari libexample_cond_exclude
hanya menyertakan kode dari both.c
karena fwk.c
dikecualikan oleh properti exclude_srcs
. Demikian pula, ini hanya bergantung pada perpustakaan bersama libboth
karena libfwk_only
dikecualikan oleh properti exclude_shared_libs
.
Ekspor header dari ekstensi VNDK
Ekstensi VNDK dapat menambahkan kelas baru atau fungsi baru ke perpustakaan bersama VNDK. Disarankan untuk menyimpan deklarasi tersebut di header independen dan menghindari mengubah header yang sudah ada.
Misalnya, file header baru include-ext/example/ext/feature_name.h
dibuat untuk ekstensi VNDK libexample_ext
:
- Android.bp
- sertakan-ext/example/ext/feature_name.h
- sertakan/contoh/contoh.h
- src/contoh.c
- src/ext/feature_name.c
Di Android.bp
berikut, libexample
ekspor hanya include
, sedangkan libexample_ext
ekspor include
dan include-ext
. Hal ini memastikan feature_name.h
tidak 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 #ifdef
guard. Namun, pastikan semua pengguna ekstensi VNDK menambahkan tanda definisikan. Anda dapat mendefinisikan cc_defaults
untuk menambahkan tanda definisikan ke cflags
dan menautkan perpustakaan bersama dengan shared_libs
.
Misalnya, untuk menambahkan fungsi anggota baru Example2::get_b()
ke ekstensi VNDK libexample2_ext
, Anda harus memodifikasi 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_
Sebuah 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
di properti defaults
:
cc_binary { name: "example2_user_executable", defaults: ["libexample2_ext_defaults"], vendor: true, }
Paket produk
Dalam sistem build Android, variabel PRODUCT_PACKAGES
menentukan executable, pustaka bersama, atau paket yang harus diinstal ke perangkat. Ketergantungan transitif dari modul tertentu secara implisit dipasang ke dalam perangkat juga.
Jika BOARD_VNDK_VERSION
diaktifkan, modul dengan vendor_available
atau vndk.enabled
mendapatkan perlakuan khusus. Jika modul kerangka kerja bergantung pada modul dengan vendor_available
atau vndk.enabled
, varian inti disertakan dalam set instalasi transitif. Jika modul vendor bergantung pada modul dengan vendor_available
, varian vendor disertakan dalam set instalasi transitif. Namun, varian modul vendor dengan vndk.enabled
diinstal baik digunakan oleh modul vendor atau tidak.
Ketika dependensi tidak terlihat oleh sistem pembangunan (misalnya perpustakaan bersama yang dapat dibuka dengan dlopen()
saat runtime), Anda harus menentukan nama modul di PRODUCT_PACKAGES
untuk menginstal modul tersebut secara eksplisit.
Jika sebuah 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. Misalnya:
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