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ını 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 derleme 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
'a bağlı olabileceğini gösterir:
Şekil 1.
Hem çerçeve yürütülebilir dosyası /system/bin/foo
hem de tedarikçi yürütülebilir dosyası /vendor/bin/bar
, libexample
'ye bağlıdır ve shared_libs
özelliklerinde libexample
vardır.
libexample
hem çerçeve modülleri hem de tedarikçi modülleri tarafından kullanılıyorsa libexample
'nin iki varyantı oluşturulur. Temel varyant (libexample
adında), çerçeve modülleri tarafından, tedarikçi varyantı (libexample.vendor
adında) ise tedarikçi modülleri tarafından kullanılır. İki varyant farklı dizinlere yüklenir:
- Temel varyant
/system/lib[64]/libexample.so
'e yüklenir. vndk.enabled
değeritrue
olduğundan tedarikçi firma varyantı, VNDK APEX'e yüklendi.
Ayrıntılı bilgi için Modül tanımı başlıklı makaleyi inceleyin.
Derleme desteğini yapılandırma
Bir ürün cihazı için tam derleme sistemi desteğini etkinleştirmek üzere BOARD_VNDK_VERSION
dosyasını BoardConfig.mk
dosyasına ekleyin:
BOARD_VNDK_VERSION := current
Bu ayarın genel bir etkisi vardır: BoardConfig.mk
içinde tanımlandığında tüm modüller kontrol edilir. Rahatsız edici bir modülü kara listeye veya beyaz listeye ekleme mekanizması olmadığından, BOARD_VNDK_VERSION
eklemeden önce tüm gereksiz bağımlılıkları temizlemeniz gerekir. Ortam değişkenlerinizde BOARD_VNDK_VERSION
ayarını yaparak 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 üstbilgilerden yararlanıyorsa header_libs
, static_libs
ve/veya shared_libs
ile bağımlılıklarını (açıkça) belirtmeniz gerekir.
VNDK APEX
Android 10 ve önceki sürümlerde, vndk.enabled
içeren modüller /system/lib[64]/vndk[-sp]-${VER}
'e yüklendi. 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 /apex/com.android.vndk.v${VER}
kanonik yolundan kullanılabilir.
Şekil 2. VNDK APEX.
Modül tanımı
Android'i BOARD_VNDK_VERSION
ile derlemek 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ımı türleri, VNDK ile ilgili çeşitli modül özellikleri ve derleme sisteminde uygulanan bağımlılık kontrolleri açıklanmaktadır.
Satıcı modülleri
Tedarikçi modülleri, tedarikçiye özgü yürütülebilir dosyalar veya tedarikçi bölümüne yüklenmesi gereken paylaşılan kitaplıklardır. Android.bp
dosyalarında tedarikçi modülleri, tedarikçi veya özel mülkü 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ımlanırsa yapı sistemi, tedarikçi modülleri ile çerçeve modülleri arasındaki bağımlılıklara izin vermez ve aşağıdaki 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çermeyenllndk_library
olmayan bir modüle bağlıdır.
Bağımlılık kontrolü, Android.bp
ürününde header_libs
, static_libs
ve shared_libs
, Android.mk
bölgesinde ise 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 tedarikçi modülleri aynı ve en son uygulamayı paylaşır. cc_library
, her LL-NDK paylaşılan kitaplığı için simge dosyasına sahip bir llndk
özelliği içerir:
cc_library { name: "libvndksupport", llndk: { symbol_file: "libvndksupport.map.txt", }, }
Simge dosyası, tedarikçi modülleri tarafından görülebilen simgeleri tanımlar. Örnek:
LIBVNDKSUPPORT { global: android_load_sphal_library; # llndk android_unload_sphal_library; # llndk local: *; };
Derleme sistemi, simge dosyasını temel alarak tedarikçi modülleri için bir stub paylaşılan kitaplık oluşturur. Bu kitaplık, BOARD_VNDK_VERSION
etkinleştirildiğinde bu kitaplıklarla bağlantı kurar. Bir simge, yalnızca aşağıdaki durumlarda stub paylaşılan kitaplığına dahil edilir:
_PRIVATE
veya_PLATFORM
ile biten bölümde tanımlanmamışsa,#platform-only
etiketi yok ve#introduce*
etiketi 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 tedarikçi) oluşturulabilir. Temel varyant, çerçeve modülü olarak, tedarikçi varyantı ise tedarikçi 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 özgüdür ve tedarikçi modülleri tarafından erişilemez.
- Çerçeve modülleri, tedarikçi varyantına her zaman erişemez.
- Tedarikçi firma varyantının
header_libs
,static_libs
ve/veyashared_libs
içinde belirtilen tüm bağımlılıklarıllndk_library
ya davendor_available
veyavndk.enabled
içeren bir modül olmalıdır. vendor_available
true
ise tedarikçi firma varyantına tüm tedarikçi firma modülleri erişebilir.vendor_available
false
ise tedarikçi varyantına yalnızca diğer VNDK veya VNDK-SP modülleri erişebilir (yanivendor:true
içeren modüllervendor_available:false
modüllerini bağlayamaz).
cc_library
veya cc_library_shared
için varsayılan kurulum yolu aşağıdaki kurallara göre belirlenir:
- Temel varyant
/system/lib[64]
'e yüklenir. - Tedarikçi firma 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 tedarikçi 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 özetlenmektedir:
vendor_available | vndk enabled |
vndk support_same_process |
Tedarikçi varyant açıklamaları |
---|---|---|---|
true |
false |
false |
Tedarikçi firma varyantları VND-ONLY şeklindedir. Paylaşılan kitaplıklar /vendor/lib[64] 'e yüklenir. |
true |
Geçersiz (Derleme hatası) | ||
true |
false |
Tedarikçi firma varyantları VNDK'dır. Paylaşılan kitaplıklar VNDK APEX'e yüklenir. | |
true |
Tedarikçi firma varyantları VNDK-SP'dir. Paylaşılan kitaplıklar VNDK APEX'e yüklenir. | ||
|
|
|
Satıcı varyantları yok. Bu modül YALNIZCA ÇERÇEVE'dir. |
true |
Geçersiz (Derleme hatası) | ||
true |
false |
Tedarikçi varyantları VNDK-Private'dir. Paylaşılan kitaplıklar, VNDK APEX'e yüklenir. Bunlar doğrudan tedarikçi modülleri tarafından kullanılmamalıdır. | |
true |
Tedarikçi firma varyantları VNDK-SP-Private'dır. Paylaşılan kitaplıklar VNDK APEX'e yüklenir. Bunlar doğrudan tedarikçi modülleri tarafından kullanılmamalıdır. |
VNDK uzantıları
VNDK uzantıları, ek API'lere sahip VNDK paylaşılan kitaplıklarıdır. Uzantıların /vendor/lib[64]/vndk[-sp]
(sürüm son eki olmadan) içine yüklenmesi ve çalışma zamanında orijinal VNDK paylaşılan kitaplıklarını geçersiz kılması
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
mülkü içeren 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
mülkü, 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şletildiği temel modül adlarından sonra adlandırılır. Örneğin,
libvndk_ext
değerinin çıkış ikilisilibvndk_ext.so
yerinelibvndk.so
olur. - VNDK uzantıları
/vendor/lib[64]/vndk
'e yüklenir. - VNDK-SP uzantıları
/vendor/lib[64]/vndk-sp
'e yüklenir. - Temel paylaşılan kitaplıklarda hem
vndk.enabled:true
hem devendor_available:true
olmalıdır.
VNDK-SP uzantısı, VNDK-SP paylaşılan kitaplığından uzanmalıdır (vndk.support_system_process
eşittir):
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 firmaların paylaşılan kitaplıklarına 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
Tedarikçi firma 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", ], }
Tedarikçi firma modülü VNDK uzantılarına bağlıysa bu VNDK uzantıları otomatik olarak /vendor/lib[64]/vndk[-sp]
ürününe yüklenir. Bir modül artık VNDK uzantısına bağlı değilse paylaşılan kitaplığı kaldırmak için CleanSpec.mk
bölümüne temiz bir adım ekleyin. Örnek:
$(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 ince farklılıklar (ör. varyantlardan birine özellik ekleme veya kaldırma) nasıl ele alınacağı açıklanmaktadır:
- Temel varyant (ör.
/system/lib[64]/libexample.so
) - Satıcı 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, tedarikçi firma varyantları ve VNDK uzantıları için varsayılan olarak __ANDROID_VNDK__
değerini tanımlar. C ön işlemci korumalarıyla kodu koruyabilirsiniz:
void all() { } #if !defined(__ANDROID_VNDK__) void framework_only() { } #endif #if defined(__ANDROID_VNDK__) void vndk_only() { } #endif
__ANDROID_VNDK__
öğesine ek olarak, Android.bp
içinde farklı cflags
veya cppflags
belirtilebilir. target.vendor
öğesinde belirtilen cflags
veya cppflags
, tedarikçi firma varyantına özeldir.
Örneğin, aşağıdaki Android.bp
libexample
ve libexample_ext
'yi 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", ], }
src/example.c
için de kod listesi şöyle:
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 simgelerle 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 simgelerle ilgili koşullar
VNDK ABI kontrol aracı, 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ı (ör.
/apex/com.android.vndk.v${VER}/lib[64]/libexample.so
) tarafından dışa aktarılan simgeler, ABI dökümlerinde tanımlanan simgelerle aynı olmalıdır (üst kümeleri değil). - VNDK uzantıları (ör.
/vendor/lib[64]/vndk/libexample.so
) tarafından dışa aktarılan simgeler, ABI dökümlerinde tanımlanan simgelerin üst kümesi olmalıdır.
VNDK tedarikçi 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ı tedarikçi varyantlarından hariç tutma
Kaynak dosyaları tedarikçi firma varyantından hariç tutmak için exclude_srcs
mülküne ekleyin. Benzer şekilde, paylaşılan kitaplıkların tedarikçi firma varyantıyla bağlanmadığından emin olmak için bu kitaplıkları exclude_shared_libs
özelliğine ekleyin. Örnek:
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
'ün temel varyantı fwk.c
ve both.c
'deki kodu içerir ve libfwk_only
ile libboth
adlı paylaşılan kitaplıklara bağlıdır. fwk.c
, exclude_srcs
özelliği tarafından hariç tutulduğundan, libexample_cond_exclude
ürününün tedarikçi firma varyantı yalnızca both.c
kaynaklı kodu içerir. Benzer şekilde, libfwk_only
, exclude_shared_libs
mülkü tarafından hariç tutulduğu için yalnızca paylaşılan kitaplık libboth
'e bağlıdır.
VNDK uzantılarından başlıkları dışa aktarma
VNDK uzantıları, VNDK paylaşılan kitaplığına yeni sınıflar veya yeni işlevler ekleyebilir. Bu beyanları bağımsız başlıklarda tutmanız ve mevcut başlıkları değiştirmemeniz ö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
örneğinde libexample
yalnızca include
'yi, libexample_ext
ise hem include
hem de include-ext
'i dışa aktarır. Bu sayede, feature_name.h
, libexample
kullanıcıları tarafından yanlışlıkla dahil edilmez:
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ın bağımsız başlık dosyalarına ayrılması mümkün değilse #ifdef
koruma eklemek de bir alternatiftir. Ancak tüm VNDK uzantısı kullanıcılarının tanımlama işaretlerini eklediğinden emin olun. cflags
öğesine işaretler eklemek ve paylaşılan kitaplıkları shared_libs
ile bağlamak için cc_defaults
öğesini tanımlayabilirsiniz.
Örneğin, VNDK uzantısı libexample2_ext
'ye yeni bir üye işlevi Example2::get_b()
eklemek için mevcut başlık dosyasını değiştirmeniz ve bir #ifdef
koruyucu 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ımlanı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ı, libexample2_ext_defaults
özelliğini defaults
mülklerine 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 dolaylı olarak yüklenir.
BOARD_VNDK_VERSION
etkinse vendor_available
veya vndk.enabled
içeren modüller özel işleme tabi tutulur. Bir çerçeve modülü vendor_available
veya vndk.enabled
içeren bir modüle bağlıysa temel varyant, aktarmalı yükleme grubuna dahil edilir. Tedarikçi firma modülü vendor_available
içeren bir modüle bağlıysa tedarikçi firma varyantı geçişli yükleme grubuna dahil edilir. Bununla birlikte, vndk.enabled
özelliğine sahip modüllerin tedarikçi varyantları, tedarikçi modülleri tarafından kullanılmalarına bakılmaksızın yüklenir.
Bağımlılıklar derleme sistemi tarafından görünmez olduğunda (ö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ı temsil eder. PRODUCT_PACKAGES
içinde tedarikçi varyantını açıkça belirtmek için modül adına .vendor
son eki ekleyin. Örnek:
cc_library { name: "libexample", srcs: ["example.c"], vendor_available: true, }
Bu örnekte libexample
, /system/lib[64]/libexample.so
yerine, libexample.vendor
ise /vendor/lib[64]/libexample.so
yerine kullanılmıştır. /vendor/lib[64]/libexample.so
'ü yüklemek için libexample.vendor
'u PRODUCT_PACKAGES
'ye ekleyin:
PRODUCT_PACKAGES += libexample.vendor