VNDK बिल्ड सिस्टम सपोर्ट

Android 8.1 और इसके बाद के वर्शन में, बिल्ड सिस्टम में VNDK की सुविधा पहले से मौजूद होती है. VNDK के साथ काम करने की सुविधा चालू होने पर, बिल्ड सिस्टम, मॉड्यूल के बीच की डिपेंडेंसी की जांच करता है. साथ ही, वेंडर मॉड्यूल के लिए वेंडर के हिसाब से वैरिएंट बनाता है और उन मॉड्यूल को तय की गई डायरेक्ट्री में अपने-आप इंस्टॉल करता है.

VNDK बिल्ड के लिए सहायता का उदाहरण

इस उदाहरण में, Android.bp मॉड्यूल की परिभाषा में libexample नाम की लाइब्रेरी के बारे में बताया गया है. vendor_available प्रॉपर्टी से पता चलता है कि फ़्रेमवर्क मॉड्यूल और वेंडर मॉड्यूल, libexample पर निर्भर हो सकते हैं:

libexample vendor_available:true और vndk.enabled:true

पहली इमेज. सहायता चालू की गई.

फ़्रेमवर्क के रन करने लायक /system/bin/foo और वेंडर के रन करने लायक /vendor/bin/bar, दोनों libexample पर निर्भर करते हैं. साथ ही, उनकी shared_libs प्रॉपर्टी में libexample होता है.

अगर libexample का इस्तेमाल फ़्रेमवर्क मॉड्यूल और वेंडर मॉड्यूल, दोनों के लिए किया जाता है, तो libexample के दो वैरिएंट बनाए जाते हैं. कोर वैरिएंट (libexample के नाम पर रखा गया) का इस्तेमाल, फ़्रेमवर्क मॉड्यूल करते हैं. वहीं, वेंडर वैरिएंट (libexample.vendor के नाम पर रखा गया) का इस्तेमाल, वेंडर मॉड्यूल करते हैं. दोनों वैरिएंट अलग-अलग डायरेक्ट्री में इंस्टॉल किए जाते हैं:

  • कोर वैरिएंट, /system/lib[64]/libexample.so में इंस्टॉल किया गया है.
  • वेंडर वैरिएंट को VNDK APEX में इंस्टॉल किया गया, क्योंकि vndk.enabled, true है.

ज़्यादा जानकारी के लिए, मॉड्यूल की परिभाषा देखें.

बिल्ड के लिए सहायता कॉन्फ़िगर करना

किसी प्रॉडक्ट डिवाइस के लिए, बिल्ड सिस्टम की पूरी सहायता चालू करने के लिए, BoardConfig.mk में BOARD_VNDK_VERSION जोड़ें:

BOARD_VNDK_VERSION := current

इस सेटिंग का ग्लोबल असर होता है: BoardConfig.mk में तय करने पर, सभी मॉड्यूल की जांच की जाती है. किसी आपत्तिजनक मॉड्यूल को ब्लैकलिस्ट या वाइटलिस्ट में जोड़ने का कोई तरीका नहीं है. इसलिए, BOARD_VNDK_VERSION जोड़ने से पहले आपको सभी गै़र-ज़रूरी डिपेंडेंसी हटानी चाहिए. अपने एनवायरमेंट वैरिएबल में BOARD_VNDK_VERSION सेट करके, मॉड्यूल की जांच और उसे कंपाइल किया जा सकता है:

$ BOARD_VNDK_VERSION=current m module_name.vendor

BOARD_VNDK_VERSION के चालू होने पर, कई डिफ़ॉल्ट ग्लोबल हेडर खोज पाथ हटा दिए जाते हैं. इनमें शामिल हैं:

  • 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

अगर कोई मॉड्यूल इन डायरेक्ट्री के हेडर पर निर्भर करता है, तो आपको header_libs, static_libs, और/या shared_libs के साथ डिपेंडेंसी की जानकारी साफ़ तौर पर देनी होगी.

VNDK APEX

Android 10 और उससे पहले के वर्शन के लिए, /system/lib[64]/vndk[-sp]-${VER} में vndk.enabled वाले मॉड्यूल इंस्टॉल किए गए थे. Android 11 और इसके बाद के वर्शन में, VNDK लाइब्रेरी को APEX फ़ॉर्मैट में पैकेज किया जाता है. साथ ही, VNDK APEX का नाम com.android.vndk.v${VER} होता है. डिवाइस कॉन्फ़िगरेशन के आधार पर, VNDK APEX फ़्लैट या नॉन-फ़्लैट होता है. साथ ही, यह कैननिकल पाथ /apex/com.android.vndk.v${VER} से उपलब्ध होता है.

VNDK APEX

दूसरी इमेज. VNDK APEX.

मॉड्यूल की परिभाषा

BOARD_VNDK_VERSION के साथ Android बनाने के लिए, आपको Android.mk या Android.bp में मॉड्यूल की परिभाषा में बदलाव करना होगा. इस सेक्शन में, अलग-अलग तरह की मॉड्यूल परिभाषाओं, VNDK से जुड़ी कई मॉड्यूल प्रॉपर्टी, और बिल्ड सिस्टम में लागू की गई डिपेंडेंसी की जांच के बारे में बताया गया है.

वेंडर मॉड्यूल

वेंडर मॉड्यूल, वेंडर के हिसाब से काम करने वाले एक्सीक्यूटेबल या शेयर की गई लाइब्रेरी होती हैं. इन्हें वेंडर के पार्टीशन में इंस्टॉल करना ज़रूरी होता है. Android.bp फ़ाइलों में, वेंडर मॉड्यूल को वेंडर या मालिकाना हक वाली प्रॉपर्टी को true पर सेट करना होगा. Android.mk फ़ाइलों में, वेंडर मॉड्यूल को LOCAL_VENDOR_MODULE या LOCAL_PROPRIETARY_MODULE को true पर सेट करना होगा.

अगर BOARD_VNDK_VERSION तय किया गया है, तो बिल्ड सिस्टम वेंडर मॉड्यूल और फ़्रेमवर्क मॉड्यूल के बीच डिपेंडेंसी की अनुमति नहीं देता. इससे गड़बड़ियां ट्रिगर होती हैं, अगर:

  • बिना vendor:true वाला मॉड्यूल, vendor:true वाले मॉड्यूल पर निर्भर करता है या
  • vendor:true वाला मॉड्यूल, llndk_library मॉड्यूल पर निर्भर करता है. हालांकि, llndk_library मॉड्यूल में vendor:true या vendor_available:true नहीं होता.

डिपेंडेंसी की जांच, Android.bp में header_libs, static_libs, और shared_libs पर लागू होती है. साथ ही, Android.mk में LOCAL_HEADER_LIBRARIES, LOCAL_STATIC_LIBRARIES, और LOCAL_SHARED_LIBRARIES पर भी लागू होती है.

एलएल-एनडीके

LL-NDK शेयर की गई लाइब्रेरी, ऐसी लाइब्रेरी होती हैं जिनमें एबीआई (एबिट्रेरी बिडिंग इंटरफ़ेस) स्थिर होते हैं. फ़्रेमवर्क और वेंडर मॉड्यूल, दोनों एक ही और नए वर्शन का इस्तेमाल करते हैं. शेयर की गई हर LL-NDK लाइब्रेरी के लिए, cc_library में एक llndk प्रॉपर्टी होती है. इसमें एक सिंबल फ़ाइल होती है:

cc_library {
    name: "libvndksupport",
    llndk: {
        symbol_file: "libvndksupport.map.txt",
    },
}

सिंबल फ़ाइल में, वेंडर मॉड्यूल को दिखने वाले सिंबल के बारे में बताया गया है. उदाहरण के लिए:

LIBVNDKSUPPORT {
  global:
    android_load_sphal_library; # llndk
    android_unload_sphal_library; # llndk
  local:
    *;
};

सिंबल फ़ाइल के आधार पर, बिल्ड सिस्टम, वेंडर मॉड्यूल के लिए एक स्टब शेयर की गई लाइब्रेरी जनरेट करता है. यह लाइब्रेरी, BOARD_VNDK_VERSION चालू होने पर, इन लाइब्रेरी से लिंक होती है. स्टब के तौर पर शेयर की गई लाइब्रेरी में किसी सिंबल को सिर्फ़ तब शामिल किया जाता है, जब:

  • _PRIVATE या _PLATFORM के साथ सेक्शन के आखिर में तय नहीं किया गया है,
  • इसमें #platform-only टैग नहीं है, और
  • उसमें #introduce* टैग न हों या टैग, टारगेट से मैच करता हो.

VNDK

Android.bp फ़ाइलों में, cc_library, cc_library_static, cc_library_shared, और cc_library_headers मॉड्यूल की परिभाषाएं, VNDK से जुड़ी तीन प्रॉपर्टी के साथ काम करती हैं: vendor_available, vndk.enabled, और vndk.support_system_process.

अगर vendor_available या vndk.enabled को true है, तो दो वैरिएंट (कोर और वेंडर) बनाए जा सकते हैं. कोर वैरिएंट को फ़्रेमवर्क मॉड्यूल के तौर पर और वेंडर वैरिएंट को वेंडर मॉड्यूल के तौर पर माना जाना चाहिए. अगर कुछ फ़्रेमवर्क मॉड्यूल इस मॉड्यूल पर निर्भर करते हैं, तो कोर वैरिएंट बनाया जाता है. अगर कुछ वेंडर मॉड्यूल इस मॉड्यूल पर निर्भर करते हैं, तो वेंडर वैरिएंट बन जाता है. बिल्ड सिस्टम, डिपेंडेंसी की इन जांचों को लागू करता है:

  • कोर वैरिएंट हमेशा फ़्रेमवर्क के लिए होता है और वेंडर के मॉड्यूल के लिए उपलब्ध नहीं होता.
  • वेंडर वैरिएंट को हमेशा फ़्रेमवर्क मॉड्यूल के लिए ऐक्सेस नहीं किया जा सकता.
  • header_libs, static_libs, और/या shared_libs में बताई गई, वेंडर वैरिएंट की सभी डिपेंडेंसी, llndk_library या vendor_available या vndk.enabled वाला मॉड्यूल होनी चाहिए.
  • अगर vendor_available, true है, तो वेंडर वैरिएंट को सभी वेंडर मॉड्यूल ऐक्सेस कर सकते हैं.
  • अगर vendor_available की वैल्यू false है, तो वेंडर वैरिएंट को सिर्फ़ अन्य वीएनडीके या वीएनडीके-एसपी मॉड्यूल से ऐक्सेस किया जा सकता है. इसका मतलब है कि vendor:true वाले मॉड्यूल vendor_available:false मॉड्यूल को लिंक नहीं कर सकते.

cc_library या cc_library_shared के लिए, इंस्टॉलेशन का डिफ़ॉल्ट पाथ इन नियमों के हिसाब से तय होता है:

  • कोर वैरिएंट, /system/lib[64] पर इंस्टॉल किया गया है.
  • वेंडर वैरिएंट का इंस्टॉलेशन पाथ अलग-अलग हो सकता है:
    • अगर vndk.enabled false है, तो वेंडर वैरिएंट /vendor/lib[64] में इंस्टॉल हो जाता है.
    • अगर vndk.enabled true है, तो वेंडर वैरिएंट को VNDK APEX(com.android.vndk.v${VER}) में इंस्टॉल किया जाता है.

नीचे दी गई टेबल में बताया गया है कि बिल्ड सिस्टम, वेंडर वैरिएंट को कैसे मैनेज करता है:

vendor_available vndk
enabled
vndk
support_same_process
वेंडर के वैरिएंट की जानकारी
true false false वेंडर के वैरिएंट सिर्फ़ वियतनामी मुद्रा में उपलब्ध हैं. शेयर की गई लाइब्रेरी, /vendor/lib[64] में इंस्टॉल होती हैं.
true अमान्य (बिल्ड करने से जुड़ी गड़बड़ी)
true false वेंडर वैरिएंट VNDK हैं. शेयर की गई लाइब्रेरी, VNDK APEX पर इंस्टॉल होती हैं.
true वेंडर वैरिएंट VNDK-SP हैं. शेयर की गई लाइब्रेरी, VNDK APEX में इंस्टॉल की जाती हैं.

false

false

false

वेंडर के कोई वैरिएंट नहीं. यह मॉड्यूल सिर्फ़ फ़्रेमवर्क के लिए है.

true अमान्य (बिल्ड करने से जुड़ी गड़बड़ी)
true false वेंडर के वैरिएंट VNDK-Private होते हैं. शेयर की गई लाइब्रेरी VNDK APEX पर इंस्टॉल होती हैं. वेंडर मॉड्यूल को इनका इस्तेमाल सीधे तौर पर नहीं करना चाहिए.
true वेंडर के वैरिएंट VNDK-SP-Private हैं. शेयर की गई लाइब्रेरी VNDK APEX पर इंस्टॉल होती हैं. वेंडर मॉड्यूल को इनका इस्तेमाल सीधे तौर पर नहीं करना चाहिए.

VNDK एक्सटेंशन

VNDK एक्सटेंशन, अतिरिक्त एपीआई वाले VNDK की शेयर की गई लाइब्रेरी होते हैं. एक्सटेंशन, /vendor/lib[64]/vndk[-sp] (वर्शन सफ़िक्स के बिना) में इंस्टॉल किए जाते हैं. ये रनटाइम के दौरान, शेयर की गई ओरिजनल VNDK लाइब्रेरी को बदल देते हैं.

VNDK एक्सटेंशन तय करना

Android 9 और इसके बाद के वर्शन में, Android.bp नेटिव तौर पर VNDK एक्सटेंशन के साथ काम करता है. VNDK एक्सटेंशन बनाने के लिए, vendor:true और extends प्रॉपर्टी के साथ एक और मॉड्यूल तय करें:

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, और extends प्रॉपर्टी वाला मॉड्यूल, VNDK एक्सटेंशन के बारे में बताता है:

  • extends प्रॉपर्टी में, VNDK की शेयर की गई लाइब्रेरी का नाम (या VNDK-SP की शेयर की गई लाइब्रेरी का नाम) होना चाहिए.
  • VNDK एक्सटेंशन (या VNDK-SP एक्सटेंशन) का नाम, उस बेस मॉड्यूल के नाम पर रखा जाता है जिससे वे एक्सटेंशन होते हैं. उदाहरण के लिए, libvndk_ext का आउटपुट बाइनरी, libvndk_ext.so के बजाय libvndk.so होता है.
  • VNDK एक्सटेंशन, /vendor/lib[64]/vndk में इंस्टॉल किए जाते हैं.
  • VNDK-SP एक्सटेंशन, /vendor/lib[64]/vndk-sp में इंस्टॉल किए गए हैं.
  • शेयर की गई बेस लाइब्रेरी में vndk.enabled:true और vendor_available:true, दोनों होने चाहिए.

VNDK-SP एक्सटेंशन, VNDK-SP शेयर की गई लाइब्रेरी से होना चाहिए (vndk.support_system_process एक जैसा होना चाहिए):

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,
    },
}

वीएनडीके एक्सटेंशन या वीएनडीके-एसपी एक्सटेंशन, शेयर की गई अन्य लाइब्रेरी पर निर्भर कर सकते हैं:

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 एक्सटेंशन का इस्तेमाल करना

अगर कोई वेंडर मॉड्यूल, VNDK एक्सटेंशन से तय किए गए अन्य एपीआई पर निर्भर करता है, तो मॉड्यूल को अपनी shared_libs प्रॉपर्टी में VNDK एक्सटेंशन का नाम बताना होगा:

// 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",
    ],
}

अगर कोई वेंडर मॉड्यूल, VNDK एक्सटेंशन पर निर्भर करता है, तो वे VNDK एक्सटेंशन /vendor/lib[64]/vndk[-sp] में अपने-आप इंस्टॉल हो जाते हैं. अगर कोई मॉड्यूल अब वीएनडीके एक्सटेंशन पर निर्भर नहीं है, तो शेयर की गई लाइब्रेरी को हटाने के लिए, CleanSpec.mk में कोई क्लीन चरण जोड़ें. उदाहरण के लिए:

$(call add-clean-step, rm -rf $(TARGET_OUT_VENDOR)/lib/libvndk.so)

शर्त के हिसाब से कंपाइल करना

इस सेक्शन में, इन तीन वीएनडीके शेयर की गई लाइब्रेरी के बीच के छोटे-छोटे अंतर (उदाहरण के लिए, किसी एक वैरिएंट में कोई सुविधा जोड़ना या हटाना) से बचने का तरीका बताया गया है:

  • मुख्य वैरिएंट (उदाहरण के लिए, /system/lib[64]/libexample.so)
  • वेंडर का वैरिएंट (उदाहरण के लिए, /apex/com.android.vndk.v${VER}/lib[64]/libexample.so)
  • VNDK एक्सटेंशन (उदाहरण के लिए, /vendor/lib[64]/vndk[-sp]/libexample.so)

कंडीशनल कंपाइलर फ़्लैग

Android बिल्ड सिस्टम, डिफ़ॉल्ट रूप से वेंडर के वैरिएंट और VNDK एक्सटेंशन के लिए __ANDROID_VNDK__ तय करता है. C प्रोसेसर्वर गार्ड की मदद से, कोड को सुरक्षित किया जा सकता है:

void all() { }

#if !defined(__ANDROID_VNDK__)
void framework_only() { }
#endif

#if defined(__ANDROID_VNDK__)
void vndk_only() { }
#endif

__ANDROID_VNDK__ के अलावा, Android.bp में अलग-अलग cflags या cppflags भी दिए जा सकते हैं. target.vendor में बताए गए cflags या cppflags, वेंडर वैरिएंट के लिए होते हैं.

उदाहरण के लिए, यह Android.bp, libexample और 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",
    ],
}

और यह 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

इन दोनों फ़ाइलों के मुताबिक, बिल्ड सिस्टम इन एक्सपोर्ट किए गए सिंबल के साथ शेयर की जाने वाली लाइब्रेरी जनरेट करता है:

इंस्टॉलेशन पाथ एक्सपोर्ट किए गए सिंबल
/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

एक्सपोर्ट किए गए सिंबल से जुड़ी ज़रूरी शर्तें

VNDK एबीआई चेकर, prebuilts/abi-dumps/vndk में मौजूद रेफ़रंस एबीआई डंप के साथ, VNDK वेंडर वैरिएंट और VNDK एक्सटेंशन के एबीआई की तुलना करता है.

  • VNDK वेंडर वैरिएंट (जैसे कि /apex/com.android.vndk.v${VER}/lib[64]/libexample.so) से एक्सपोर्ट किए गए सिंबल, एबीआई डंप में तय किए गए सिंबल (न कि उनके सुपरसेट) के बराबर होने चाहिए.
  • VNDK एक्सटेंशन (उदाहरण के लिए, /vendor/lib[64]/vndk/libexample.so) से एक्सपोर्ट किए गए सिंबल, एबीआई डंप में तय किए गए सिंबल के सुपरसेट होने चाहिए.

अगर VNDK वेंडर वैरिएंट या VNDK एक्सटेंशन, ऊपर बताई गई ज़रूरी शर्तों को पूरा नहीं करते हैं, तो VNDK एबीआई चेकर, बिल्ड से जुड़ी गड़बड़ियां दिखाता है और बिल्ड को रोक देता है.

वेंडर वैरिएंट से सोर्स फ़ाइलों या शेयर की गई लाइब्रेरी को बाहर रखना

वेंडर वैरिएंट से सोर्स फ़ाइलों को हटाने के लिए, उन्हें exclude_srcs प्रॉपर्टी में जोड़ें. इसी तरह, शेयर की गई लाइब्रेरी को वेंडर वैरिएंट से लिंक न करने के लिए, उन लाइब्रेरी को exclude_shared_libs प्रॉपर्टी में जोड़ें. उदाहरण के लिए:

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"],
        },
    },
}

इस उदाहरण में, libexample_cond_exclude के मुख्य वैरिएंट में fwk.c और both.c का कोड शामिल है. यह कोड, शेयर की गई लाइब्रेरी libfwk_only और libboth पर निर्भर करता है. libexample_cond_exclude के वेंडर वैरिएंट में सिर्फ़ both.c का कोड शामिल होता है, क्योंकि fwk.c को exclude_srcs प्रॉपर्टी से बाहर रखा गया है. इसी तरह, यह सिर्फ़ शेयर की गई लाइब्रेरी libboth पर निर्भर करता है, क्योंकि libfwk_only को exclude_shared_libs प्रॉपर्टी से बाहर रखा गया है.

VNDK एक्सटेंशन से हेडर एक्सपोर्ट करना

VNDK एक्सटेंशन, VNDK की शेयर की गई लाइब्रेरी में नई क्लास या नए फ़ंक्शन जोड़ सकता है. हमारा सुझाव है कि इन एलानों को इंडिपेंडेंट हेडर में रखें और मौजूदा हेडर में बदलाव न करें.

उदाहरण के लिए, VNDK एक्सटेंशन libexample_ext के लिए, एक नई हेडर फ़ाइल include-ext/example/ext/feature_name.h बनाई गई है:

  • Android.bp
  • include-ext/example/ext/feature_name.h
  • include/example/example.h
  • src/example.c
  • src/ext/feature_name.c

नीचे दिए गए Android.bp में, libexample सिर्फ़ include को एक्सपोर्ट करता है, जबकि libexample_ext include और include-ext, दोनों को एक्सपोर्ट करता है. इससे यह पक्का होता है कि feature_name.h के उपयोगकर्ता, 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",
    },
}

अगर एक्सटेंशन को अलग-अलग हेडर फ़ाइलों में अलग नहीं किया जा सकता, तो #ifdef गार्ड जोड़ने का विकल्प है. हालांकि, पक्का करें कि सभी VNDK एक्सटेंशन के उपयोगकर्ता, डिफ़ाइन फ़्लैग जोड़ें. cflags में फ़्लैग जोड़ने और शेयर की गई लाइब्रेरी को shared_libs से लिंक करने के लिए, cc_defaults तय किया जा सकता है.

उदाहरण के लिए, VNDK एक्सटेंशन libexample2_ext में नया सदस्य फ़ंक्शन Example2::get_b() जोड़ने के लिए, आपको मौजूदा हेडर फ़ाइल में बदलाव करना होगा और #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_

libexample2_ext_defaults नाम का cc_defaults, 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",
    ],
}

libexample2_ext के उपयोगकर्ता अपनी defaults प्रॉपर्टी में libexample2_ext_defaults को शामिल कर सकते हैं:

cc_binary {
    name: "example2_user_executable",
    defaults: ["libexample2_ext_defaults"],
    vendor: true,
}

प्रॉडक्ट पैकेज

Android बिल्ड सिस्टम में, वैरिएबल PRODUCT_PACKAGES उन एक्सीक्यूटेबल, शेयर की गई लाइब्रेरी या पैकेज के बारे में बताता है जिन्हें डिवाइस में इंस्टॉल किया जाना चाहिए. चुने गए मॉड्यूल की ट्रांज़िशन डिपेंडेंसी, डिवाइस में अपने-आप इंस्टॉल हो जाती हैं.

अगर BOARD_VNDK_VERSION चालू है, तो vendor_available या vndk.enabled वाले मॉड्यूल को खास तरीके से प्रोसेस किया जाता है. अगर कोई फ़्रेमवर्क मॉड्यूल vendor_available या vndk.enabled वाले मॉड्यूल पर निर्भर करता है, तो मुख्य वैरिएंट को ट्रांज़िटिव इंस्टॉलेशन सेट में शामिल किया जाता है. अगर कोई वेंडर मॉड्यूल, vendor_available वाले मॉड्यूल पर निर्भर करता है, तो वेंडर वैरिएंट को ट्रांज़िशन वाले इंस्टॉलेशन सेट में शामिल किया जाता है. हालांकि, vndk.enabled वाले मॉड्यूल के वेंडर वैरिएंट इंस्टॉल किए जाते हैं, भले ही वेंडर मॉड्यूल उनका इस्तेमाल करते हों या नहीं.

जब डिपेंडेंसी, बिल्ड सिस्टम को नहीं दिखती हैं, तो उन मॉड्यूल को साफ़ तौर पर इंस्टॉल करने के लिए, आपको PRODUCT_PACKAGES में मॉड्यूल के नाम बताने होंगे. उदाहरण के लिए, शेयर की गई लाइब्रेरी, जिन्हें रनटाइम में dlopen() से खोला जा सकता है.

अगर किसी मॉड्यूल में vendor_available या vndk.enabled है, तो मॉड्यूल का नाम उसके मुख्य वैरिएंट के लिए होता है. PRODUCT_PACKAGES में वेंडर वैरिएंट के बारे में साफ़ तौर पर बताने के लिए, मॉड्यूल के नाम के बाद .vendor सफ़िक्स जोड़ें. उदाहरण के लिए:

cc_library {
    name: "libexample",
    srcs: ["example.c"],
    vendor_available: true,
}

इस उदाहरण में, libexample का मतलब /system/lib[64]/libexample.so और libexample.vendor का मतलब /vendor/lib[64]/libexample.so है. /vendor/lib[64]/libexample.so इंस्टॉल करने के लिए, libexample.vendor को PRODUCT_PACKAGES में जोड़ें:

PRODUCT_PACKAGES += libexample.vendor