सोर्स जनरेटर

इस पेज पर, इस बारे में अहम जानकारी दी गई है कि जनरेट किया गया सोर्स कैसे काम करता है और बिल्ड सिस्टम में इसका इस्तेमाल कैसे किया जा सकता है.

सभी सोर्स जनरेटर, बिल्ड-सिस्टम से मिलती-जुलती सुविधाएं देते हैं. सोर्स जनरेशन के इस्तेमाल के तीन उदाहरणों में, बाइन्ड करने वाले टूल, AIDL इंटरफ़ेस, और प्रोटोबस इंटरफ़ेस का इस्तेमाल करके C बाइंडिंग जनरेट की जा रही हैं.

जनरेट किए गए सोर्स से क्रेट

सोर्स कोड जनरेट करने वाले हर Rust मॉड्यूल को क्रेट की तरह इस्तेमाल किया जा सकता है अगर इसे rust_library के तौर पर परिभाषित किया जाता. इसका मतलब है कि इसे rustlibs, rlibs, और dylibs प्रॉपर्टी में डिपेंडेंसी के तौर पर तय किया जा सकता है. सबसे सही इस्तेमाल प्लैटफ़ॉर्म कोड का पैटर्न, जनरेट किए गए सोर्स को क्रेट के तौर पर इस्तेमाल करना है. जनरेट किए गए सोर्स के लिए, include! मैक्रो का इस्तेमाल किया जा सकता है. हालांकि, इसका मुख्य मकसद external/ में मौजूद तीसरे पक्ष के कोड के साथ काम करना है.

कुछ मामलों में प्लैटफ़ॉर्म कोड, जनरेट किए गए सोर्स का इस्तेमाल अब भी include!() मैक्रो, जैसे कि जब सोर्स जनरेट करने के लिए genrule मॉड्यूल का इस्तेमाल किया जाता है एक अनोखे अंदाज़ में.

जनरेट किए गए सोर्स को शामिल करने के लिए, include!() का इस्तेमाल करना

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

पूर्वापेक्षा

यह उदाहरण इस आधार पर दिया गया है कि आपने rust_bindgen मॉड्यूल (libbuzz_bindgen) तय किया है और include!() मैक्रो का इस्तेमाल करने के लिए, जनरेट किए गए सोर्स को शामिल करने के तरीके पर आगे बढ़ सकते हैं. अगर आपने ऐसा नहीं किया है, तो कृपया रस्ट बाइंडिंग मॉड्यूल तय करना पर जाएं, libbuzz_bindgen बनाएं और फिर यहां वापस आएं.

ध्यान दें कि इसकी बिल्ड-फ़ाइल के हिस्से, सभी सोर्स जनरेटर पर लागू होते हैं.

जनरेट किए गए सोर्स को शामिल करने का तरीका

इस कॉन्टेंट का इस्तेमाल करके external/rust/hello_bindgen/Android.bp बनाएं:

rust_binary {
   name: "hello_bzip_bindgen_include",
   srcs: [
         // The primary rust source file must come first in this list.
         "src/lib.rs",

         // The module providing the bindgen bindings is
         // included in srcs prepended by ":".
         ":libbuzz_bindgen",
    ],

    // Dependencies need to be redeclared when generated source is used via srcs.
    shared_libs: [
        "libbuzz",
    ],
}

इस कॉन्टेंट के साथ external/rust/hello_bindgen/src/bindings.rs बनाएं:

#![allow(clippy::all)]
#![allow(non_upper_case_globals)]
#![allow(non_camel_case_types)]
#![allow(non_snake_case)]
#![allow(unused)]
#![allow(missing_docs)]

// Note that "bzip_bindings.rs" here must match the source_stem property from
// the rust_bindgen module.
include!(concat!(env!("OUT_DIR"), "/bzip_bindings.rs"));

इस कॉन्टेंट का इस्तेमाल करके external/rust/hello_bindgen/src/lib.rs बनाएं:

mod bindings;

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

जनरेट किए गए सोर्स के लिए क्रेट क्यों बनाए जाते हैं

C/C++ कंपाइलर के उलट, rustc सिर्फ़ एक सोर्स फ़ाइल को स्वीकार करता है, जो किसी बाइनरी या लाइब्रेरी के एंट्री पॉइंट को दिखाती है. यह उम्मीद करती है कि ट्री को इस तरह से बनाया गया है कि सभी ज़रूरी सोर्स फ़ाइलें अपने-आप खोजा गया. इसका मतलब है कि जनरेट किए गए सोर्स को, सोर्स में रखा जाना चाहिए ट्री, या सोर्स में शामिल करने के डायरेक्टिव के ज़रिए दिया गया हो:

include!("/path/to/hello.rs");

Rust कम्यूनिटी, build.rs स्क्रिप्ट और Cargo के बिल्ड एनवायरमेंट के बारे में अनुमानों पर निर्भर करती है, ताकि इस अंतर के साथ काम किया जा सके. जब यह बनता है, तो cargo निर्देश OUT_DIR एनवायरमेंट वैरिएबल सेट करता है जिसमें build.rs स्क्रिप्ट के लिए, जनरेट किए गए सोर्स कोड को शामिल करने की उम्मीद की जाती है. सोर्स कोड शामिल करने के लिए, इस कमांड का इस्तेमाल करें:

include!(concat!(env!("OUT_DIR"), "/hello.rs"));

इससे सूंग के लिए एक चुनौती पैदा होती है, क्योंकि हर मॉड्यूल के लिए आउटपुट दिए जाते हैं उसकी out/ डायरेक्ट्री1. ऐसा कोई OUT_DIR नहीं है जहां डिपेंडेंसी अपने जनरेट किए गए सोर्स को आउटपुट करती हैं.

प्लैटफ़ॉर्म कोड के लिए, एओएसपी पैकेजिंग से जनरेट किए गए सोर्स को एक क्रेट में प्राथमिकता देता है. इंपोर्ट न होने की कई वजहें हो सकती हैं:

  • जनरेट की गई सोर्स फ़ाइल के नामों को एक जैसा होने से रोकना.
  • बॉयलरप्लेट कोड कम करें पूरे पेड़ के आस-पास मौजूद चीज़ों के रखरखाव की ज़रूरत होती है. कोई भी बॉयलरप्लेट जनरेट किए गए सोर्स कंपाइल के लिए ज़रूरी है एक क्रेट को एक ही जगह से मैनेज किया जा सकता है.
  • जनरेट किए गए कोड और उसके आस-पास के क्रेट के बीच, इंप्लिसिट2 इंटरैक्शन से बचें.
  • आम तौर पर इस्तेमाल किए जाने वाले सोर्स को डाइनैमिक तरीके से लिंक करके, मेमोरी और डिस्क पर दबाव कम करें.

इस वजह से, Android के Rust सोर्स जनरेशन मॉड्यूल टाइप, ऐसा कोड जनरेट करते हैं जिसे क्रेट के तौर पर कंपाइल और इस्तेमाल किया जा सकता है. सूंग अब भी बिना किसी बदलाव के तीसरे पक्ष के बैंक स्टेटमेंट का इस्तेमाल करता है किसी मॉड्यूल के लिए जनरेट की गई सोर्स डिपेंडेंसी, एक हर मॉड्यूल में कॉपी हो जाती हैं और कार्गो जैसी ही डायरेक्ट्री होती है. ऐसे मामलों में, Soong मॉड्यूल को कंपाइल करते समय, OUT_DIR एनवायरमेंट वैरिएबल को उस डायरेक्ट्री में सेट करता है, ताकि जनरेट किया गया सोर्स ढूंढा जा सके. हालांकि, पहले बताई गई वजहों से, प्लैटफ़ॉर्म कोड में इस तरीके का इस्तेमाल सिर्फ़ तब करना चाहिए, जब ज़रूरी हो.


  1. हालांकि, C/C++ और इससे मिलती-जुलती भाषाओं के लिए कोई समस्या मौजूद नहीं है, क्योंकि जनरेट किए गए सोर्स का पाथ सीधे कंपाइलर को दिया जाता है.

  2. include!, टेक्स्ट को शामिल करके काम करता है. इसलिए, यह नेमस्पेस में मौजूद वैल्यू का रेफ़रंस दे सकता है, नेमस्पेस में बदलाव कर सकता है या #![foo] जैसे कंस्ट्रक्ट का इस्तेमाल कर सकता है. इस तरह के इंटरैक्शन को बनाए रखना मुश्किल हो सकता है. जब क्रेट के बाकी हिस्सों के साथ इंटरैक्ट करना ज़रूरी हो, तो हमेशा मैक्रो का इस्तेमाल करें.