VNDK बिल्ड सिस्टम के लिए सहायता

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

वीएनडीके बिल्ड सपोर्ट का उदाहरण

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

libexample vendor_available:true and 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 का इस्तेमाल करके, साफ़ तौर पर डिपेंडेंसी के बारे में बताना होगा.

वीएनडीके APEX

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

वीएनडीके APEX

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

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

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

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

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

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

  • vendor:true के बिना कोई मॉड्यूल, vendor:true वाले मॉड्यूल पर निर्भर करता है या
  • vendor:true वाला कोई मॉड्यूल, ऐसे नॉन-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

एलएल-एनडीके शेयर की गई लाइब्रेरी, स्टेबल एबीआइ वाली शेयर की गई लाइब्रेरी होती हैं. फ़्रेमवर्क और वेंडर मॉड्यूल, दोनों में एक ही और नया वर्शन इस्तेमाल किया जाता है. हर एलएल-एनडीके शेयर की गई लाइब्रेरी के लिए, 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* टैग नहीं हैं या टैग टारगेट से मेल खाता है.

वीएनडीके

Android.bp फ़ाइलों में, cc_library, cc_library_static, cc_library_shared, और cc_library_headers मॉड्यूल की परिभाषाएं, वीएनडीके से जुड़ी तीन प्रॉपर्टी के साथ काम करती हैं: 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_system_process
वेंडर के वैरिएंट की जानकारी
true false false वेंडर वैरिएंट, VND-ONLY होते हैं. शेयर की गई लाइब्रेरी, /vendor/lib[64] में इंस्टॉल की जाती हैं.
true अमान्य (बनाने में गड़बड़ी)
true false वेंडर के वैरिएंट, वीएनडीके हैं. शेयर की गई लाइब्रेरी, वीएनडीके एपेक्स में इंस्टॉल की जाती हैं.
true वेंडर के वैरिएंट VNDK-SP हैं. शेयर की गई लाइब्रेरी, VNDK APEX में इंस्टॉल की जाती हैं.

false

false

false

वेंडर के कोई वैरिएंट नहीं हैं. यह मॉड्यूल FWK-ONLY है.

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

वीएनडीके एक्सटेंशन

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

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

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

  • extends प्रॉपर्टी में, वीएनडीके की शेयर की गई लाइब्रेरी के बेस वर्शन का नाम (या वीएनडीके-एसपी की शेयर की गई लाइब्रेरी का नाम) बताना ज़रूरी है.
  • वीएनडीके एक्सटेंशन (या वीएनडीके-एसपी एक्सटेंशन) का नाम, उस बेस मॉड्यूल के नाम पर रखा जाता है जिससे वे एक्सटेंड होते हैं. उदाहरण के लिए, 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.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 एक्सटेंशन का इस्तेमाल करना

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

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

अगर कोई वेंडर मॉड्यूल, वीएनडीके एक्सटेंशन पर निर्भर करता है, तो वे वीएनडीके एक्सटेंशन, /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)
  • वीएनडीके एक्सटेंशन (जैसे, /vendor/lib[64]/vndk[-sp]/libexample.so)

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

Android बिल्ड सिस्टम, वेंडर के वैरिएंट और वीएनडीके एक्सटेंशन के लिए डिफ़ॉल्ट रूप से __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

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

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

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

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

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

सोर्स फ़ाइलों को वेंडर वैरिएंट से बाहर रखने के लिए, उन्हें 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 का कोड शामिल होता है. ऐसा इसलिए, क्योंकि exclude_srcs प्रॉपर्टी ने fwk.c को शामिल नहीं किया है. इसी तरह, यह सिर्फ़ शेयर की गई लाइब्रेरी libboth पर निर्भर करता है, क्योंकि exclude_shared_libs प्रॉपर्टी के ज़रिए libfwk_only को बाहर रखा गया है.

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 में फ़्लैग जोड़ने के लिए, cc_defaults को तय किया जा सकता है. साथ ही, शेयर की गई लाइब्रेरी को shared_libs से लिंक किया जा सकता है.

उदाहरण के लिए, 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 के उपयोगकर्ताओं के लिए, cc_defaults नाम की libexample2_ext_defaults को इस तरह से तय किया गया है:

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 वाले मॉड्यूल के वेंडर वैरिएंट इंस्टॉल किए जाते हैं. भले ही, उनका इस्तेमाल वेंडर मॉड्यूल करते हों या न करते हों.

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

अगर किसी मॉड्यूल में 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 को इंस्टॉल करने के लिए, PRODUCT_PACKAGES में libexample.vendor जोड़ें:

PRODUCT_PACKAGES += libexample.vendor