বিল্ড সিস্টেমটি rust_bindgen মডিউল টাইপের মাধ্যমে বাইন্ডজেন বাইন্ডিং তৈরি করতে সহায়তা করে। Bindgen C লাইব্রেরিতে রাস্ট FFI বাইন্ডিং প্রদান করে (কিছু সীমিত C++ সমর্থন সহ, যার জন্য 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);
}

একটি rust_bindgen মডিউল সংজ্ঞায়িত করুন

একটি মোড়ক শিরোনাম সংজ্ঞায়িত করুন, 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 মডিউল সংজ্ঞায়িত করতে এই বিভাগটি ব্যবহার করলে, উত্স জেনারেটর পৃষ্ঠায় পূর্বশর্তটিতে ফিরে যান। যদি না হয়, পরবর্তী বিভাগগুলির সাথে এগিয়ে যান।

একটি ক্রেট হিসাবে bindings ব্যবহার করুন

নিম্নলিখিত বিষয়বস্তু সহ 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 কল করুন।

বাইন্ডজেন বাইন্ডিং পরীক্ষা করুন

বাইন্ডজেন বাইন্ডিংয়ে সাধারণত মেমরি লেআউটের অমিল রোধ করার জন্য অনেকগুলি তৈরি করা লেআউট পরীক্ষা থাকে। AOSP সুপারিশ করে যে আপনার কাছে এই পরীক্ষাগুলির জন্য একটি পরীক্ষা মডিউল সংজ্ঞায়িত করা আছে এবং পরীক্ষাগুলি আপনার প্রকল্পের সাধারণ পরীক্ষার স্যুটের অংশ হিসাবে চালানো হয়।

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 মডিউলগুলিতে [":__subpackages__"] এর একটি visibility বৈশিষ্ট্য রয়েছে, যা শুধুমাত্র একই Android.bp ফাইলের মডিউল বা এটির নিচে থাকা ডিরেক্টরি অনুক্রমের মডিউলগুলিকে এটি দেখতে অনুমতি দেবে৷ এটি দুটি উদ্দেশ্য পরিবেশন করে:

  • এটি গাছের অন্য কোথাও কাঁচা সি বাইন্ডিং ব্যবহারকে নিরুৎসাহিত করে।
  • এটি স্ট্যাটিক এবং ডাইনামিক লিঙ্কেজের মিশ্রণের সাথে ডায়মন্ড লিঙ্কিং সমস্যাগুলি এড়িয়ে যায়।

সাধারণত, আপনি একই ডিরেক্টরি ট্রিতে বাইন্ডিং হিসাবে যুক্ত করা উত্পন্ন মডিউলের চারপাশে একটি নিরাপদ মোড়ক লাইব্রেরি প্রদান করা উচিত যা অন্যান্য বিকাশকারীদের ব্যবহার করার উদ্দেশ্যে। এটি আপনার ব্যবহারের ক্ষেত্রে কাজ না করলে, আপনি দৃশ্যমানতায় অতিরিক্ত প্যাকেজ যোগ করতে পারেন। অতিরিক্ত দৃশ্যমানতার সুযোগ যোগ করার সময়, অনুগ্রহ করে খেয়াল রাখবেন যে আপনি দুটি স্কোপ যোগ করবেন না যা ভবিষ্যতে একই প্রক্রিয়ার সাথে সংযুক্ত হতে পারে, কারণ এটি লিঙ্ক করতে ব্যর্থ হতে পারে।

উল্লেখযোগ্য মরিচা_বিন্ডজেন বৈশিষ্ট্য

নীচে সংজ্ঞায়িত বৈশিষ্ট্যগুলি গুরুত্বপূর্ণ সাধারণ বৈশিষ্ট্যগুলি ছাড়াও যা সমস্ত মডিউলে প্রযোজ্য। এগুলি হয় রাস্ট বাইন্ডজেন মডিউলগুলির জন্য বিশেষভাবে গুরুত্বপূর্ণ, বা rust_bindgen মডিউল প্রকারের জন্য নির্দিষ্ট অনন্য আচরণ প্রদর্শন করে।

স্টেম, নাম, ক্রেট_নাম

rust_bindgen লাইব্রেরি ভেরিয়েন্ট তৈরি করে, তাই তারা stem , name এবং crate_name বৈশিষ্ট্যগুলির জন্য rust_library মডিউলগুলির সাথে একই প্রয়োজনীয়তা ভাগ করে। রেফারেন্সের জন্য উল্লেখযোগ্য মরিচা লাইব্রেরি বৈশিষ্ট্য দেখুন।

wrapper_src

এটি একটি র‍্যাপার হেডার ফাইলের আপেক্ষিক পথ যা এই বাইন্ডিংয়ের জন্য প্রয়োজনীয় হেডারগুলিকে অন্তর্ভুক্ত করে। ফাইল এক্সটেনশন নির্ধারণ করে কিভাবে হেডারকে ব্যাখ্যা করতে হয় এবং ডিফল্টরূপে কোন -std পতাকা ব্যবহার করতে হবে তা নির্ধারণ করে। এক্সটেনশনটি .hh বা .hpp না হলে এটি একটি C শিরোনাম বলে ধরে নেওয়া হয়। যদি আপনার C++ হেডারে অবশ্যই অন্য কোনো এক্সটেনশন থাকে, তাহলে ডিফল্ট আচরণকে ওভাররাইড করতে cpp_std প্রপার্টি সেট করুন যা ফাইলটিকে একটি C ফাইল বলে ধরে নেয়।

উৎস_স্টেম

এটি উত্পন্ন উৎস ফাইলের ফাইলের নাম। এই ক্ষেত্রটি অবশ্যই সংজ্ঞায়িত করা উচিত, এমনকি যদি আপনি বাইন্ডিংগুলিকে একটি ক্রেট হিসাবে ব্যবহার করেন, যেহেতু stem সম্পত্তি শুধুমাত্র জেনারেট করা লাইব্রেরি ভেরিয়েন্টগুলির জন্য আউটপুট ফাইলের নাম নিয়ন্ত্রণ করে। যদি একটি মডিউল একাধিক উৎস জেনারেটরের উপর নির্ভর করে (যেমন bindgen এবং protobuf ) rustlibs মাধ্যমে ক্রেটের পরিবর্তে উত্স হিসাবে, আপনাকে অবশ্যই নিশ্চিত করতে হবে যে সমস্ত উত্স জেনারেটর যেগুলি সেই মডিউলের নির্ভরতাগুলির অনন্য source_stem মান রয়েছে। নির্ভরশীল মডিউলগুলি সমস্ত SourceProvider নির্ভরতা থেকে উত্স কপি করে যা একটি সাধারণ OUT_DIR ডিরেক্টরিতে srcs এ সংজ্ঞায়িত করা হয়েছে, তাই source_stem এ সংঘর্ষের ফলে উৎপন্ন উত্স ফাইলগুলি OUT_DIR ডিরেক্টরিতে ওভাররাইট করা হবে৷

c_std

এটি একটি স্ট্রিং যা সি-স্ট্যান্ডার্ড সংস্করণ ব্যবহার করতে হবে তা উপস্থাপন করে। বৈধ মান নীচে তালিকাভুক্ত করা হয়েছে:

  • একটি নির্দিষ্ট সংস্করণ, যেমন "gnu11"
  • "experimental" , যা build/soong/cc/config/global.go এ বিল্ড সিস্টেম দ্বারা সংজ্ঞায়িত একটি মান, যখন সেগুলি উপলব্ধ থাকে তখন C++1z এর মতো খসড়া সংস্করণগুলি ব্যবহার করতে পারে৷
  • আনসেট বা "" , যা নির্দেশ করে যে বিল্ড সিস্টেম ডিফল্ট ব্যবহার করা উচিত।

এটি সেট করা থাকলে, ফাইল এক্সটেনশন উপেক্ষা করা হয় এবং হেডারটিকে একটি C শিরোনাম বলে ধরে নেওয়া হয়। এটি cpp_std হিসাবে একই সময়ে সেট করা যাবে না।

cpp_std

cpp_std হল একটি স্ট্রিং যা সি স্ট্যান্ডার্ড সংস্করণ ব্যবহার করতে হবে। বৈধ মান:

  • একটি নির্দিষ্ট সংস্করণ, যেমন "gnu++11"
  • "experimental" , যা build/soong/cc/config/global.go এ বিল্ড সিস্টেম দ্বারা সংজ্ঞায়িত একটি মান, যখন সেগুলি উপলব্ধ থাকে তখন C++1z এর মতো খসড়া সংস্করণগুলি ব্যবহার করতে পারে৷
  • আনসেট বা "" , যা নির্দেশ করে যে বিল্ড সিস্টেম ডিফল্ট ব্যবহার করা উচিত।

এটি সেট করা থাকলে, ফাইল এক্সটেনশন উপেক্ষা করা হয় এবং হেডারটিকে একটি C++ শিরোনাম বলে ধরে নেওয়া হয়। এটি c_std হিসাবে একই সময়ে সেট করা যাবে না।

cflags

cflags সঠিকভাবে শিরোনাম ব্যাখ্যা করার জন্য প্রয়োজনীয় ঝনঝন পতাকার একটি স্ট্রিং তালিকা প্রদান করে।

custom_bindgen

উন্নত ব্যবহারের ক্ষেত্রে, বিন্ডজেন একটি লাইব্রেরি হিসাবে ব্যবহার করা যেতে পারে, একটি API প্রদান করে যা একটি কাস্টম রাস্ট বাইনারির অংশ হিসাবে ব্যবহার করা যেতে পারে। custom_bindgen ক্ষেত্রটি একটি rust_binary_host মডিউলের মডিউলের নাম নেয়, যা সাধারণ bindgen বাইনারির পরিবর্তে bindgen API ব্যবহার করে।

এই কাস্টম বাইনারিটি অবশ্যই bindgen এর সাথে অনুরূপ আর্গুমেন্ট আশা করবে, যেমন

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

এর বেশিরভাগই bindgen লাইব্রেরি নিজেই পরিচালনা করে। এই ব্যবহারের একটি উদাহরণ দেখতে, external/rust/crates/libsqlite3-sys/android/build.rs দেখুন।

অতিরিক্তভাবে, লাইব্রেরির সংকলন নিয়ন্ত্রণের জন্য লাইব্রেরি বৈশিষ্ট্যের সম্পূর্ণ সেট উপলব্ধ, যদিও এইগুলি খুব কমই সংজ্ঞায়িত বা পরিবর্তনের প্রয়োজন।

হ্যান্ডেল_স্ট্যাটিক_ইনলাইন এবং স্ট্যাটিক_ইনলাইন_লাইব্রেরি

এই দুটি বৈশিষ্ট্য একত্রে ব্যবহার করা এবং স্ট্যাটিক ইনলাইন ফাংশনগুলির জন্য র‍্যাপার উৎপাদনের অনুমতি দেয় যা রপ্তানি করা বিন্ডজেন বাইন্ডিংয়ে অন্তর্ভুক্ত করা যেতে পারে।

সেগুলি ব্যবহার করার জন্য, handle_static_inline: true সেট করুন এবং static_inline_library একটি সংশ্লিষ্ট cc_library_static এ সেট করুন যা rust_bindgen মডিউলকে উৎস ইনপুট হিসাবে সংজ্ঞায়িত করে।

উদাহরণ ব্যবহার:

    rust_bindgen {
        name: "libbindgen",
        wrapper_src: "src/any.h",
        crate_name: "bindgen",
        stem: "libbindgen",
        source_stem: "bindings",

        // Produce bindings for static inline fucntions
        handle_static_inline: true,
        static_inline_library: "libbindgen_staticfns"
    }

    cc_library_static {
        name: "libbindgen_staticfns",

        // This is the rust_bindgen module defined above
        srcs: [":libbindgen"],

        // The include path to the header file in the generated c file is
        // relative to build top.
        include_dirs: ["."],
    }