Android 8.1 ve sonraki sürümlerde derleme sisteminde yerleşik VNDK desteği bulunur. VNDK desteği etkinleştirildiğinde derleme sistemi, modüller arasındaki bağımlılıkları kontrol eder, satıcı modülleri için satıcıya özel bir varyant oluşturur ve bu modülleri belirlenen dizinlere otomatik olarak yükler.
VNDK oluşturma desteği örneği
Bu örnekte, Android.bp modül tanımı libexample adlı bir kitaplığı tanımlar. vendor_available özelliği, çerçeve modüllerinin ve tedarikçi modüllerinin libexample öğesine bağlı olabileceğini gösterir:
Şekil 1. desteği etkinleştirildi.
Hem çerçeve yürütülebilir dosyası /system/bin/foo hem de satıcı yürütülebilir dosyası /vendor/bin/bar, libexample öğesine bağlıdır ve shared_libs özelliklerinde libexample öğesini içerir.
libexample hem çerçeve modülleri hem de tedarikçi modülleri tarafından kullanılıyorsa libexample'nın iki varyantı oluşturulur. Çekirdek varyant (libexample'dan sonra adlandırılır) çerçeve modülleri tarafından, satıcı varyantı (libexample.vendor'dan sonra adlandırılır) ise satıcı modülleri tarafından kullanılır. İki varyant farklı dizinlere yüklenir:
- Temel varyant,
/system/lib[64]/libexample.sokonumuna yüklenir. vndk.enabled,trueolduğu için satıcı varyantı VNDK APEX'e yüklenir.
Daha fazla bilgi için Modül tanımı başlıklı makaleyi inceleyin.
Derleme desteğini yapılandırma
Bir ürün cihazında tam derleme sistemi desteğini etkinleştirmek için BoardConfig.mk'ye BOARD_VNDK_VERSION ekleyin:
BOARD_VNDK_VERSION := current
Bu ayar genel bir etkiye sahiptir: BoardConfig.mk içinde tanımlandığında tüm modüller kontrol edilir. İhlal eden bir modülü kara listeye veya beyaz listeye alma mekanizması olmadığından BOARD_VNDK_VERSION öğesini eklemeden önce tüm gereksiz bağımlılıkları temizlemeniz gerekir. Ortam değişkenlerinizde BOARD_VNDK_VERSION değerini ayarlayarak bir modülü test edip derleyebilirsiniz:
$ BOARD_VNDK_VERSION=current m module_name.vendor
BOARD_VNDK_VERSION etkinleştirildiğinde, birkaç varsayılan genel üstbilgi arama yolu kaldırılır. Bunlardan bazıları:
frameworks/av/includeframeworks/native/includeframeworks/native/opengl/includehardware/libhardware/includehardware/libhardware_legacy/includehardware/ril/includelibnativehelper/includelibnativehelper/include_deprecatedsystem/core/includesystem/media/audio/include
Bir modül bu dizinlerdeki başlıklara bağlıysa header_libs, static_libs ve/veya shared_libs ile bağımlılıkları (açıkça) belirtmeniz gerekir.
VNDK APEX
Android 10 ve önceki sürümlerde, vndk.enabled simgesi olan modüller /system/lib[64]/vndk[-sp]-${VER} konumuna yükleniyordu. Android 11 ve sonraki sürümlerde VNDK kitaplıkları APEX biçiminde paketlenir ve VNDK APEX'in adı com.android.vndk.v${VER} olur. Cihaz yapılandırmasına bağlı olarak VNDK APEX düzleştirilir veya düzleştirilmez ve standart yoldan /apex/com.android.vndk.v${VER} kullanılabilir.

Şekil 2. VNDK APEX.
Modül tanımı
Android'i BOARD_VNDK_VERSION ile oluşturmak için Android.mk veya Android.bp içinde modül tanımını düzeltmeniz gerekir. Bu bölümde, farklı modül tanımları, VNDK ile ilgili çeşitli modül özellikleri ve derleme sisteminde uygulanan bağımlılık kontrolleri açıklanmaktadır.
Tedarikçi modülleri
Tedarikçi modülleri, tedarikçiye özel yürütülebilir dosyalar veya paylaşılan kitaplıklardır ve tedarikçi bölümüne yüklenmelidir. Android.bp dosyalarında, sağlayıcı modülleri sağlayıcı veya tescilli özelliği true olarak ayarlamalıdır.
Android.mk dosyalarında, tedarikçi modülleri LOCAL_VENDOR_MODULE veya LOCAL_PROPRIETARY_MODULE değerini true olarak ayarlamalıdır.
BOARD_VNDK_VERSION tanımlanmışsa derleme sistemi, tedarikçi modülleri ile çerçeve modülleri arasındaki bağımlılıklara izin vermez ve şu durumlarda hata verir:
vendor:trueiçermeyen bir modül,vendor:trueiçeren bir modüle bağlıysa veyavendor:trueiçeren bir modül,vendor:trueveyavendor_available:trueiçermeyen birllndk_librarymodülüne bağlıdır.
Bağımlılık kontrolü, Android.bp içindeki header_libs, static_libs ve shared_libs ile Android.mk içindeki LOCAL_HEADER_LIBRARIES, LOCAL_STATIC_LIBRARIES ve LOCAL_SHARED_LIBRARIES için geçerlidir.
LL-NDK
LL-NDK paylaşılan kitaplıkları, kararlı ABI'lere sahip paylaşılan kitaplıklardır. Hem çerçeve hem de satıcı modülleri aynı ve en son uygulamayı kullanır. Her bir LL-NDK paylaşılan kitaplığı için cc_library, sembol dosyası içeren bir llndk özelliği içerir:
cc_library { name: "libvndksupport", llndk: { symbol_file: "libvndksupport.map.txt", }, }
Sembol dosyası, tedarikçi modüllerine görünür olan sembolleri açıklar. Örneğin:
LIBVNDKSUPPORT { global: android_load_sphal_library; # llndk android_unload_sphal_library; # llndk local: *; };
Derleme sistemi, sembol dosyasına göre tedarikçi modülleri için bir saplama paylaşılan kitaplığı oluşturur. Bu kitaplıklar, BOARD_VNDK_VERSION etkinleştirildiğinde bu kitaplıklarla bağlantı oluşturur. Bir sembol, yalnızca aşağıdaki durumlarda kısa paylaşılan kitaplığa dahil edilir:
_PRIVATEveya_PLATFORMile biten bölümde tanımlanmamış#platform-onlyetiketi yoksa ve#introduce*etiketleri yok veya etiket hedefle eşleşiyor.
VNDK
Android.bp dosyalarında cc_library,
cc_library_static, cc_library_shared ve
cc_library_headers modül tanımları VNDK ile ilgili üç özelliği destekler: vendor_available, vndk.enabled ve
vndk.support_system_process.
vendor_available veya vndk.enabled, true ise iki varyant (çekirdek ve sağlayıcı) oluşturulabilir. Temel varyant, çerçeve modülü olarak; satıcı varyantı ise satıcı modülü olarak değerlendirilmelidir. Bazı çerçeve modülleri bu modüle bağlıysa temel varyant oluşturulur. Bazı tedarikçi modülleri bu modüle bağlıysa tedarikçi varyantı oluşturulur. Derleme sistemi, aşağıdaki bağımlılık kontrollerini zorunlu kılar:
- Temel varyant her zaman yalnızca çerçeveye özeldir ve satıcı modüllerine erişilemez.
- Tedarikçi varyantına, çerçeve modülleri tarafından hiçbir zaman erişilemez.
header_libs,static_libsve/veyashared_libsiçinde belirtilen tedarikçi varyantının tüm bağımlılıklarıllndk_libraryveyavendor_availableya davndk.enablediçeren bir modül olmalıdır.vendor_availabletrueise tedarikçi varyantına tüm tedarikçi modülleri erişebilir.vendor_availablefalseise tedarikçi varyantına yalnızca diğer VNDK veya VNDK-SP modülleri erişebilir (ör.vendor:trueiçeren modüllervendor_available:falsemodüllerine bağlanamaz).
cc_library veya cc_library_shared için varsayılan kurulum yolu aşağıdaki kurallara göre belirlenir:
- Temel varyant
/system/lib[64]konumuna yüklenir. - Tedarikçi varyantı yükleme yolu değişiklik gösterebilir:
vndk.enabledfalseise tedarikçi varyantı/vendor/lib[64]'ye yüklenir.vndk.enabledtrueise sağlayıcı varyantı VNDK APEX'e(com.android.vndk.v${VER}) yüklenir.
Aşağıdaki tabloda, derleme sisteminin tedarikçi varyantlarını nasıl işlediği özetlenmiştir:
| vendor_available | vndk enabled |
vndk support_system_process |
Tedarikçi varyant açıklamaları |
|---|---|---|---|
true |
false |
false |
Tedarikçi varyantları yalnızca VND cinsindendir. Paylaşılan kitaplıklar /vendor/lib[64]'ya yüklenir. |
true |
Geçersiz (Derleme hatası) | ||
true |
false |
Tedarikçi varyantları VNDK'dır. Paylaşılan kitaplıklar VNDK APEX'e yüklenir. | |
true |
Tedarikçi varyantları VNDK-SP'dir. Paylaşılan kitaplıklar VNDK APEX'e yüklenir. | ||
|
|
|
Satıcı varyantı yok. Bu modül FWK-ONLY'dir. |
true |
Geçersiz (Derleme hatası) | ||
true |
false |
Tedarikçi varyantları VNDK-Private'tır. Paylaşılan kitaplıklar VNDK APEX'e yüklenir. Bunlar, tedarikçi modülleri tarafından doğrudan kullanılmamalıdır. | |
true |
Tedarikçi varyantları VNDK-SP-Private'tır. Paylaşılan kitaplıklar VNDK APEX'e yüklenir. Bunlar, tedarikçi modülleri tarafından doğrudan kullanılmamalıdır. |
VNDK uzantıları
VNDK uzantıları, ek API'ler içeren VNDK paylaşılan kitaplıklarıdır. Uzantılar, /vendor/lib[64]/vndk[-sp]'ya (sürüm soneki olmadan) yüklenir ve çalışma zamanında orijinal VNDK paylaşılan kitaplıklarının üzerine yazar.
VNDK uzantılarını tanımlama
Android 9 ve sonraki sürümlerde Android.bp, VNDK uzantılarını yerel olarak destekler. VNDK uzantısı oluşturmak için vendor:true ve extends özelliği olan başka bir modül tanımlayın:
cc_library { name: "libvndk", vendor_available: true, vndk: { enabled: true, }, } cc_library { name: "libvndk_ext", vendor: true, vndk: { enabled: true, extends: "libvndk", }, }
vendor:true, vndk.enabled:true ve extends özelliklerine sahip bir modül, VNDK uzantısını tanımlar:
extendsözelliği, temel bir VNDK paylaşılan kitaplık adını (veya VNDK-SP paylaşılan kitaplık adını) belirtmelidir.- VNDK uzantıları (veya VNDK-SP uzantıları), genişledikleri temel modül adlarına göre adlandırılır. Örneğin,
libvndk_extöğesinin çıkış ikilisilibvndk_ext.soyerinelibvndk.soolur. - VNDK uzantıları
/vendor/lib[64]/vndkiçine yüklenir. - VNDK-SP uzantıları
/vendor/lib[64]/vndk-spiçine yüklenir. - Temel paylaşılan kitaplıklar hem
vndk.enabled:truehem devendor_available:trueiçermelidir.
VNDK-SP uzantısı, VNDK-SP paylaşılan kitaplığından türetilmelidir
(vndk.support_system_process eşit olmalıdır):
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, }, }
VNDK uzantıları (veya VNDK-SP uzantıları) diğer tedarikçi tarafından paylaşılan kitaplıklara bağlı olabilir:
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, }
VNDK uzantılarını kullanma
Bir satıcı modülü, VNDK uzantıları tarafından tanımlanan ek API'lere bağlıysa modül, shared_libs özelliğinde VNDK uzantısının adını belirtmelidir:
// 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", ], }
Bir satıcı modülü VNDK uzantılarına bağlıysa bu VNDK uzantıları otomatik olarak /vendor/lib[64]/vndk[-sp]'ya yüklenir. Bir modül artık VNDK uzantısına bağlı değilse paylaşılan kitaplığı kaldırmak için CleanSpec.mk'ya temiz bir adım ekleyin. Örneğin:
$(call add-clean-step, rm -rf $(TARGET_OUT_VENDOR)/lib/libvndk.so)
Koşullu derleme
Bu bölümde, aşağıdaki üç VNDK paylaşılan kitaplığı arasındaki küçük farklılıkların (ör. varyantlardan birine özellik ekleme veya varyantlardan birinden özellik kaldırma) nasıl ele alınacağı açıklanmaktadır:
- Temel varyant (ör.
/system/lib[64]/libexample.so) - Tedarikçi varyantı (ör.
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so) - VNDK uzantısı (ör.
/vendor/lib[64]/vndk[-sp]/libexample.so)
Koşullu derleyici işaretleri
Android derleme sistemi, varsayılan olarak tedarikçi varyantları ve VNDK uzantıları için __ANDROID_VNDK__ tanımlar. Kodu C ön işlemci korumalarıyla koruyabilirsiniz:
void all() { }
#if !defined(__ANDROID_VNDK__)
void framework_only() { }
#endif
#if defined(__ANDROID_VNDK__)
void vndk_only() { }
#endif
__ANDROID_VNDK__'ya ek olarak, Android.bp içinde farklı cflags veya cppflags belirtilebilir. target.vendor içinde belirtilen cflags veya cppflags, satıcı varyantına özgüdür.
Örneğin, aşağıdaki Android.bp, libexample ve libexample_ext öğelerini tanımlar:
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şağıda src/example.c kod listesi yer almaktadır:
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() { }
#endifBu iki dosyaya göre derleme sistemi, aşağıdaki dışa aktarılan sembollerle paylaşılan kitaplıklar oluşturur:
| Yükleme yolu | Dışa aktarılan simgeler |
|---|---|
/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 |
Dışa aktarılan sembollerle ilgili koşullar
VNDK ABI denetleyicisi, VNDK tedarikçi varyantlarının ve VNDK uzantılarının ABI'sini prebuilts/abi-dumps/vndk altındaki referans ABI dökümleriyle karşılaştırır.
- VNDK tedarikçi varyantları tarafından dışa aktarılan semboller (ör.
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so), ABI dökümlerinde tanımlanan sembollerle aynı olmalıdır (üst kümeleri olmamalıdır). - VNDK uzantıları tarafından dışa aktarılan semboller (ör.
/vendor/lib[64]/vndk/libexample.so), ABI dökümlerinde tanımlanan sembollerin üst kümeleri olmalıdır.
VNDK satıcı varyantları veya VNDK uzantıları yukarıdaki şartlara uymazsa VNDK ABI denetleyicisi derleme hataları verir ve derlemeyi durdurur.
Kaynak dosyaları veya paylaşılan kitaplıkları satıcı varyantlarının dışında tutma
Kaynak dosyaları tedarikçi varyantının dışında tutmak için bu dosyaları exclude_srcs özelliğine ekleyin. Benzer şekilde, paylaşılan kitaplıkların satıcı varyantıyla bağlantılı olmadığından emin olmak için bu kitaplıkları exclude_shared_libs özelliğine ekleyin. Örneğin:
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"], }, }, }
Bu örnekte, libexample_cond_exclude çekirdek varyantı, fwk.c ve both.c kodunu içerir ve libfwk_only ile libboth paylaşılan kitaplıklarına bağlıdır. libexample_cond_exclude öğesinin sağlayıcı varyantı, fwk.c öğesi exclude_srcs özelliği tarafından hariç tutulduğu için yalnızca both.c öğesindeki kodu içerir. Benzer şekilde, libfwk_only, exclude_shared_libs özelliği tarafından hariç tutulduğu için yalnızca paylaşılan kitaplığa libboth bağlıdır.
VNDK uzantılarından başlıkları dışa aktarma
VNDK uzantısı, VNDK paylaşılan kitaplığına yeni sınıflar veya yeni işlevler ekleyebilir. Bu bildirimlerin bağımsız başlıklarda tutulması ve mevcut başlıkların değiştirilmemesi önerilir.
Örneğin, VNDK
uzantısı libexample_ext için yeni bir başlık dosyası include-ext/example/ext/feature_name.h oluşturulur:
- Android.bp
- include-ext/example/ext/feature_name.h
- include/example/example.h
- src/example.c
- src/ext/feature_name.c
Aşağıdaki Android.bp, libexample dışa aktarma işlemlerinde yalnızca include dışa aktarılırken libexample_ext dışa aktarma işlemlerinde hem include hem de include-ext dışa aktarılır. Bu sayede, feature_name.h öğesinin libexample kullanıcıları tarafından yanlışlıkla eklenmesi önlenir:
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", }, }
Uzantıları bağımsız başlık dosyalarına ayırmak mümkün değilse alternatif olarak #ifdef korumaları eklenebilir. Ancak tüm VNDK uzantısı kullanıcılarının tanımlama işaretlerini eklediğinden emin olun. cc_defaults tanımlayarak cflags'ye tanımlama işaretleri ekleyebilir ve paylaşılan kitaplıkları shared_libs ile bağlayabilirsiniz.
Örneğin, VNDK uzantısına libexample2_ext yeni bir üye işlevi Example2::get_b() eklemek için mevcut başlık dosyasını değiştirmeniz ve bir #ifdef koruması eklemeniz gerekir:
#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_
libexample2_ext kullanıcıları için libexample2_ext_defaults adlı bir cc_defaults tanımlanmıştır:
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", ], }
libexample2_ext kullanıcıları, defaults özelliklerine libexample2_ext_defaults ekleyebilir:
cc_binary {
name: "example2_user_executable",
defaults: ["libexample2_ext_defaults"],
vendor: true,
}Ürün paketleri
Android derleme sisteminde PRODUCT_PACKAGES değişkeni, cihaza yüklenmesi gereken yürütülebilir dosyaları, paylaşılan kitaplıkları veya paketleri belirtir. Belirtilen modüllerin geçişli bağımlılıkları da cihaza örtülü olarak yüklenir.
BOARD_VNDK_VERSION etkinse vendor_available veya vndk.enabled içeren modüller özel işlem görür. Bir çerçeve modülü, vendor_available veya vndk.enabled içeren bir modüle bağlıysa temel varyant, geçişli yükleme kümesine dahil edilir. Bir tedarikçi modülü
vendor_available içeren bir modüle bağlıysa tedarikçi varyantı
geçişli yükleme grubuna dahil edilir. Ancak, vndk.enabled içeren modüllerin tedarikçi varyantları, tedarikçi modülleri tarafından kullanılıp kullanılmadıklarına bakılmaksızın yüklenir.
Bağımlılıklar derleme sistemi için görünür olmadığında (ör. çalışma zamanında dlopen() ile açılabilen paylaşılan kitaplıklar), bu modülleri açıkça yüklemek için PRODUCT_PACKAGES içinde modül adlarını belirtmeniz gerekir.
Bir modülde vendor_available veya vndk.enabled varsa modül adı, temel varyantını ifade eder. PRODUCT_PACKAGES içinde satıcı varyantını açıkça belirtmek için modül adına .vendor sonekini ekleyin. Örneğin:
cc_library { name: "libexample", srcs: ["example.c"], vendor_available: true, }
Bu örnekte libexample, /system/lib[64]/libexample.so, libexample.vendor ise /vendor/lib[64]/libexample.so anlamına gelir. /vendor/lib[64]/libexample.so uygulamasını yüklemek için libexample.vendor'ı PRODUCT_PACKAGES'a ekleyin:
PRODUCT_PACKAGES += libexample.vendor