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.so
konumuna yüklenir. vndk.enabled
,true
olduğ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/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
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:true
içermeyen bir modül,vendor:true
içeren bir modüle bağlıysa veyavendor:true
içeren bir modül,vendor:true
veyavendor_available:true
içermeyen birllndk_library
modü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:
_PRIVATE
veya_PLATFORM
ile biten bölümde tanımlanmamış#platform-only
etiketi 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_libs
ve/veyashared_libs
içinde belirtilen tedarikçi varyantının tüm bağımlılıklarıllndk_library
veyavendor_available
ya davndk.enabled
içeren bir modül olmalıdır.vendor_available
true
ise tedarikçi varyantına tüm tedarikçi modülleri erişebilir.vendor_available
false
ise tedarikçi varyantına yalnızca diğer VNDK veya VNDK-SP modülleri erişebilir (ör.vendor:true
içeren modüllervendor_available:false
modü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.enabled
false
ise tedarikçi varyantı/vendor/lib[64]
'ye yüklenir.vndk.enabled
true
ise 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.so
yerinelibvndk.so
olur. - VNDK uzantıları
/vendor/lib[64]/vndk
içine yüklenir. - VNDK-SP uzantıları
/vendor/lib[64]/vndk-sp
içine yüklenir. - Temel paylaşılan kitaplıklar hem
vndk.enabled:true
hem devendor_available:true
iç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() { } #endif
Bu 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