बिल्ड सिस्टम rust_bindgen मॉड्यूल प्रकार के माध्यम से बाइंडजेन बाइंडिंग उत्पन्न करने का समर्थन करता है। बाइंडजेन सी लाइब्रेरीज़ को रस्ट एफएफआई बाइंडिंग प्रदान करता है (कुछ सीमित सी++ समर्थन के साथ, जिसके लिए cppstd प्रॉपर्टी सेट करने की आवश्यकता होती है)।

बुनियादी रस्ट_बाइंडजेन उपयोग

बाइंडजेन का उपयोग करने वाले मॉड्यूल को कैसे परिभाषित किया जाए और उस मॉड्यूल को क्रेट के रूप में कैसे उपयोग किया जाए, इसका एक उदाहरण इस प्रकार है। यदि आपको किसी include!() मैक्रो के माध्यम से बाइंडजेन बाइंडिंग का उपयोग करने की आवश्यकता है, जैसे बाहरी कोड के लिए, तो सोर्स जेनरेटर पेज देखें।

रस्ट से कॉल करने के लिए उदाहरण सी लाइब्रेरी

एक उदाहरण सी लाइब्रेरी जो रस्ट में उपयोग के लिए एक संरचना और फ़ंक्शन को परिभाषित करती है।

external/rust/libbuzz/libbuzz.h

typedef struct foo {
    int x;
} foo;

void fizz(int i, foo* cs);

external/rust/libbuzz/libbuzz.c

#include <stdio.h>
#include "libbuzz.h"

void fizz(int i, foo* my_foo){
    printf("hello from c! i = %i, my_foo->x = %i\n", i, my_foo->x);
}

रस्ट_बाइंडजेन मॉड्यूल को परिभाषित करें

एक रैपर हेडर, external/rust/libbuzz/libbuzz_wrapper.h को परिभाषित करें, जिसमें सभी प्रासंगिक हेडर शामिल हैं:

// Include headers that are required for generating bindings in a wrapper header.
#include "libbuzz.h"

Android.bp फ़ाइल को external/rust/libbuzz/Android.bp के रूप में परिभाषित करें:

cc_library {
    name: "libbuzz",
    srcs: ["libbuzz.c"],
}

rust_bindgen {
     name: "libbuzz_bindgen",

     // Crate name that's used to generate the rust_library variants.
     crate_name: "buzz_bindgen",

     // Path to the wrapper source file.
     wrapper_src: "libbuzz_wrapper.h",

     // 'source_stem' controls the output filename.
     // This is the filename that's used in an include! macro.
     //
     // In this case, we just use "bindings", which produces
     // "bindings.rs".
     source_stem: "bindings",

     // Bindgen-specific flags and options to customize the bindings.
     // See the bindgen manual for more information.
     bindgen_flags: ["--verbose"],

     // Clang flags to be used when generating the bindings.
     cflags: ["-DSOME_FLAG"],

     // Shared, static, and header libraries which export the necessary
     // include directories must be specified.
     //
     // These libraries will also be included in the crate if static,
     // or propagated to dependents if shared.
     // static_libs: ["libbuzz"]
     // header_libs: ["libbuzz"]
     shared_libs: ["libbuzz"],
}

बाइंडजेन फ़्लैग का उपयोग करने के बारे में अधिक जानने के लिए, जेनरेटेड बाइंडिंग को अनुकूलित करने पर बाइंडजेन मैनुअल अनुभाग देखें।

यदि आपने इस अनुभाग का उपयोग include!() मैक्रो का उपयोग करने के लिए एक पूर्व शर्त के रूप में एक rust_bindgen मॉड्यूल को परिभाषित करने के लिए किया है, तो स्रोत जेनरेटर पृष्ठ पर पूर्व शर्त पर वापस लौटें। यदि नहीं, तो अगले अनुभागों के साथ आगे बढ़ें।

टोकरे के रूप में बाइंडिंग का उपयोग करें

निम्नलिखित सामग्री के साथ external/rust/hello_bindgen/Android.bp बनाएं:

rust_binary {
   name: "hello_bindgen",
   srcs: ["main.rs"],

   // Add the rust_bindgen module as if it were a rust_library dependency.
   rustlibs: ["libbuzz_bindgen"],
}

निम्नलिखित सामग्री के साथ external/rust/hello_bindgen/src/main.rs बनाएं:

//! Example crate for testing bindgen bindings

fn main() {
    let mut x = buzz_bindgen::foo { x: 2 };
    unsafe { buzz_bindgen::fizz(1, &mut x as *mut buzz_bindgen::foo) }
}

अंत में, बाइनरी बनाने के लिए m hello_bindgen पर कॉल करें।

बाइंडजेन बाइंडिंग का परीक्षण करें

मेमोरी लेआउट बेमेल को रोकने के लिए बाइंडजेन बाइंडिंग में आमतौर पर कई जेनरेट किए गए लेआउट परीक्षण होते हैं। एओएसपी अनुशंसा करता है कि आपके पास इन परीक्षणों के लिए एक परीक्षण मॉड्यूल परिभाषित है, और परीक्षण आपके प्रोजेक्ट के सामान्य परीक्षण सूट के हिस्से के रूप में चलते हैं।

इनके लिए एक परीक्षण बाइनरी को external/rust/hello_bindgen/Android.bp में एक rust_test मॉड्यूल को परिभाषित करके आसानी से तैयार किया जा सकता है:

rust_test {
    name: "bindings_test",
    srcs: [
        ":libbuzz_bindgen",
    ],
    crate_name: "buzz_bindings_test",
    test_suites: ["general-tests"],
    auto_gen_config: true,

    // Be sure to disable lints as the generated source
    // is not guaranteed to be lint-free.
    clippy_lints: "none",
    lints: "none",
}

दृश्यता और जुड़ाव

जेनरेटेड बाइंडिंग आमतौर पर बहुत छोटी होती हैं, क्योंकि उनमें प्रकार की परिभाषाएँ, फ़ंक्शन हस्ताक्षर और संबंधित स्थिरांक शामिल होते हैं। परिणामस्वरूप, इन पुस्तकालयों को गतिशील रूप से जोड़ना आम तौर पर बेकार है। हमने इन मॉड्यूल के लिए डायनामिक लिंकेज को अक्षम कर दिया है ताकि rustlibs के माध्यम से उनका उपयोग करने से स्वचालित रूप से एक स्थिर संस्करण का चयन हो सके।

डिफ़ॉल्ट रूप से, rust_bindgen मॉड्यूल में visibility गुण [":__subpackages__"] होता है, जो केवल उसी Android.bp फ़ाइल या निर्देशिका पदानुक्रम में इसके नीचे वाले मॉड्यूल को इसे देखने की अनुमति देगा। इससे दो उद्देश्य पूरे होते हैं:

  • यह पेड़ में अन्यत्र कच्चे सी बाइंडिंग के उपयोग को हतोत्साहित करता है।
  • यह स्थिर और गतिशील लिंकेज के मिश्रण से डायमंड लिंकिंग समस्याओं से बचाता है।

आम तौर पर, आपको जेनरेट किए गए मॉड्यूल के चारों ओर एक सुरक्षित रैपर लाइब्रेरी प्रदान करनी चाहिए जिसे आपने बाइंडिंग के समान निर्देशिका ट्री में जोड़ा है जो अन्य डेवलपर्स के उपयोग के लिए है। यदि यह आपके उपयोग के मामले में काम नहीं करता है, तो आप दृश्यता में अतिरिक्त पैकेज जोड़ सकते हैं। अतिरिक्त दृश्यता स्कोप जोड़ते समय, कृपया ध्यान रखें कि आप दो स्कोप न जोड़ें जो भविष्य में एक ही प्रक्रिया से जुड़े हों, क्योंकि यह लिंक करने में विफल हो सकता है।

उल्लेखनीय रस्ट_बाइंडजेन गुण

नीचे परिभाषित गुण उन महत्वपूर्ण सामान्य गुणों के अतिरिक्त हैं जो सभी मॉड्यूल पर लागू होते हैं। ये या तो रस्ट बाइंडजेन मॉड्यूल के लिए विशेष रूप से महत्वपूर्ण हैं, या rust_bindgen मॉड्यूल प्रकार के लिए विशिष्ट अद्वितीय व्यवहार प्रदर्शित करते हैं।

तना, नाम, टोकरा_नाम

rust_bindgen लाइब्रेरी वेरिएंट तैयार करता है, इसलिए वे stem , name और crate_name गुणों के लिए rust_library मॉड्यूल के साथ समान आवश्यकताएं साझा करते हैं। संदर्भ के लिए उल्लेखनीय रस्ट लाइब्रेरी गुण देखें।

रैपर_src

यह एक रैपर हेडर फ़ाइल का सापेक्ष पथ है जिसमें इन बाइंडिंग के लिए आवश्यक हेडर शामिल हैं। फ़ाइल एक्सटेंशन यह निर्धारित करता है कि हेडर की व्याख्या कैसे की जाए और यह निर्धारित करता है कि डिफ़ॉल्ट रूप से किस -std ध्वज का उपयोग किया जाए। इसे C हेडर माना जाता है जब तक कि एक्सटेंशन .hh या .hpp न हो। यदि आपके C++ हेडर में कोई अन्य एक्सटेंशन होना चाहिए, तो डिफ़ॉल्ट व्यवहार को ओवरराइड करने के लिए cpp_std प्रॉपर्टी सेट करें जो मानता है कि फ़ाइल एक C फ़ाइल है।

source_stem

यह जेनरेट की गई स्रोत फ़ाइल का फ़ाइल नाम है। इस फ़ील्ड को परिभाषित किया जाना चाहिए , भले ही आप बाइंडिंग को क्रेट के रूप में उपयोग कर रहे हों, क्योंकि stem प्रॉपर्टी केवल जेनरेट किए गए लाइब्रेरी वेरिएंट के लिए आउटपुट फ़ाइल नाम को नियंत्रित करती है। यदि कोई मॉड्यूल rustlibs के माध्यम से क्रेट के बजाय स्रोत के रूप में एकाधिक स्रोत जेनरेटर (जैसे bindgen और protobuf ) पर निर्भर करता है, तो आपको यह सुनिश्चित करना होगा कि सभी स्रोत जेनरेटर जो उस मॉड्यूल की निर्भरता हैं, उनके पास अद्वितीय source_stem मान हैं। आश्रित मॉड्यूल सभी SourceProvider निर्भरताओं से स्रोतों की प्रतिलिपि बनाते हैं जिन्हें srcs में एक सामान्य OUT_DIR निर्देशिका में परिभाषित किया गया है, इसलिए source_stem में टकराव के परिणामस्वरूप उत्पन्न स्रोत फ़ाइलें OUT_DIR निर्देशिका में अधिलेखित हो जाएंगी।

c_std

यह एक स्ट्रिंग है जो दर्शाती है कि किस सी-मानक संस्करण का उपयोग करना है। मान्य मान नीचे सूचीबद्ध हैं:

  • एक विशिष्ट संस्करण, जैसे "gnu11"
  • "experimental" , जो बिल्ड सिस्टम द्वारा build/soong/cc/config/global.go में परिभाषित एक मान है, उपलब्ध होने पर C++1z जैसे ड्राफ्ट संस्करणों का उपयोग कर सकता है।
  • अनसेट या "" , जो इंगित करता है कि बिल्ड सिस्टम डिफ़ॉल्ट का उपयोग किया जाना चाहिए।

यदि इसे सेट किया जाता है, तो फ़ाइल एक्सटेंशन को अनदेखा कर दिया जाता है और हेडर को C हेडर मान लिया जाता है। इसे cpp_std के समान समय पर सेट नहीं किया जा सकता।

cpp_std

cpp_std एक स्ट्रिंग है जो दर्शाती है कि किस C मानक संस्करण का उपयोग करना है। मान्य मान:

  • एक विशिष्ट संस्करण, जैसे "gnu++11"
  • "experimental" , जो बिल्ड सिस्टम द्वारा build/soong/cc/config/global.go में परिभाषित एक मान है, उपलब्ध होने पर C++1z जैसे ड्राफ्ट संस्करणों का उपयोग कर सकता है।
  • अनसेट या "" , जो इंगित करता है कि बिल्ड सिस्टम डिफ़ॉल्ट का उपयोग किया जाना चाहिए।

यदि इसे सेट किया जाता है, तो फ़ाइल एक्सटेंशन को अनदेखा कर दिया जाता है और हेडर को C++ हेडर मान लिया जाता है। इसे c_std के साथ एक ही समय में सेट नहीं किया जा सकता है।

cflags

cflags हेडर की सही व्याख्या करने के लिए आवश्यक क्लैंग फ़्लैग की एक स्ट्रिंग सूची प्रदान करता है।

कस्टम_बाइंडजेन

उन्नत उपयोग के मामलों के लिए, बाइंडजेन को एक लाइब्रेरी के रूप में उपयोग किया जा सकता है, एक एपीआई प्रदान करता है जिसे कस्टम रस्ट बाइनरी के हिस्से के रूप में हेरफेर किया जा सकता है। custom_bindgen फ़ील्ड एक rust_binary_host मॉड्यूल का मॉड्यूल नाम लेता है, जो सामान्य bindgen बाइनरी के बजाय बाइंडजेन एपीआई का उपयोग करता है।

इस कस्टम बाइनरी को bindgen के समान तर्कों की अपेक्षा करनी चाहिए, जैसे

$ my_bindgen [flags] wrapper_header.h -o [output_path] -- [clang flags]

इनमें से अधिकांश को bindgen लाइब्रेरी द्वारा ही नियंत्रित किया जाता है। इस उपयोग का एक उदाहरण देखने के लिए, external/rust/crate/libsqlite3-sys/android/build.rs पर जाएँ।

इसके अतिरिक्त, लाइब्रेरी के संकलन को नियंत्रित करने के लिए लाइब्रेरी गुणों का पूरा सेट उपलब्ध है, हालाँकि इन्हें परिभाषित करने या बदलने की शायद ही कभी आवश्यकता होती है।