इस पेज पर, जनरेट किए गए सोर्स के काम करने के तरीके और उसे बिल्ड सिस्टम में इस्तेमाल करने के तरीके के बारे में खास जानकारी दी गई है.
सभी सोर्स जनरेटर, बिल्ड-सिस्टम की एक जैसी सुविधाएं देते हैं. सोर्स जनरेशन के इस्तेमाल के तीन उदाहरणों में, बाइन्ड करने वाले टूल, एआईडीएल इंटरफ़ेस, और प्रोटोबस इंटरफ़ेस का इस्तेमाल करके C बाइंडिंग जनरेट की जा रही हैं.
जनरेट किए गए सोर्स से क्रेट
सोर्स कोड जनरेट करने वाले हर Rust मॉड्यूल को क्रेट के तौर पर इस्तेमाल किया जा सकता है. ठीक वैसे ही जैसे कि उसे rust_library
के तौर पर तय किया गया हो. इसका मतलब है कि इसे rustlibs
, rlibs
, और dylibs
प्रॉपर्टी में डिपेंडेंसी के तौर पर तय किया जा सकता है. प्लैटफ़ॉर्म कोड के इस्तेमाल का सबसे अच्छा पैटर्न, जनरेट किए गए सोर्स को क्रेट के तौर पर इस्तेमाल करना है. जनरेट किए गए सोर्स के लिए include!
मैक्रो का इस्तेमाल किया जा सकता है. हालांकि, इसका मुख्य मकसद external/
में मौजूद तीसरे पक्ष के कोड के साथ काम करना है.
कुछ मामलों में, प्लैटफ़ॉर्म कोड अब भी include!()
मैक्रो के ज़रिए जनरेट किए गए सोर्स का इस्तेमाल कर सकता है. जैसे, जब किसी खास तरीके से सोर्स जनरेट करने के लिए genrule
मॉड्यूल का इस्तेमाल किया जाता है.
जनरेट किए गए सोर्स को शामिल करने के लिए, include!() का इस्तेमाल करें
जनरेट किए गए सोर्स को क्रेट के तौर पर इस्तेमाल करने के बारे में, हर मॉड्यूल पेज पर दिए गए उदाहरणों में बताया गया है. इस सेक्शन में, include!()
मैक्रो की मदद से जनरेट किए गए सोर्स का रेफ़रंस देने का तरीका बताया गया है. ध्यान दें कि यह प्रोसेस, सभी सोर्स जनरेटर के लिए एक जैसी होती है.
पूर्वापेक्षा
यह उदाहरण इस आधार पर दिया गया है कि आपने rust_bindgen
मॉड्यूल (libbuzz_bindgen
) तय किया है और include!()
मैक्रो का इस्तेमाल करने के लिए, जनरेट किए गए सोर्स को शामिल करने के तरीके पर आगे बढ़ सकते हैं. अगर आपने ऐसा नहीं किया है, तो कृपया rust bindgen मॉड्यूल तय करना पर जाएं और 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"));
इससे Soong के लिए एक समस्या आती है, क्योंकि हर मॉड्यूल के आउटपुट को अपनी out/
डायरेक्ट्री1 में रखा जाता है. ऐसा कोई OUT_DIR
नहीं है जहां डिपेंडेंसी, जनरेट किए गए सोर्स को आउटपुट करती है.
प्लैटफ़ॉर्म कोड के लिए, AOSP जनरेट किए गए सोर्स को पैकेज करके, ऐसे क्रेट में डालना चाहता है जिसे इंपोर्ट किया जा सके. ऐसा कई वजहों से किया जाता है:
- जनरेट की गई सोर्स फ़ाइल के नामों को एक जैसा होने से रोकना.
- पूरे ट्री में, छोटे-मोटे बदलाव वाले कोड को कम करें. जनरेट किए गए सोर्स को कंपाइल करके क्रेट में बदलने के लिए, ज़रूरी किसी भी बॉयलरप्लेट को एक ही जगह से मैनेज किया जा सकता है.
- जनरेट किए गए कोड और आस-पास के क्रेट के बीच,2 इंप्लिसिट इंटरैक्शन से बचें.
- आम तौर पर इस्तेमाल होने वाले जनरेट किए गए सोर्स को डाइनैमिक तौर पर लिंक करके, मेमोरी और डिस्क पर दबाव कम करें.
इस वजह से, Android के Rust सोर्स जनरेशन मॉड्यूल टाइप, ऐसा कोड जनरेट करते हैं जिसे क्रेट के तौर पर कंपाइल और इस्तेमाल किया जा सकता है. Soong अब भी तीसरे पक्ष के क्रेट के साथ काम करता है. इसके लिए, ज़रूरी है कि किसी मॉड्यूल के लिए जनरेट की गई सभी सोर्स डिपेंडेंसी, Cargo की तरह ही हर मॉड्यूल की एक डायरेक्ट्री में कॉपी की गई हों. ऐसे मामलों में, Soong मॉड्यूल को कंपाइल करते समय, OUT_DIR
एनवायरमेंट वैरिएबल को उस डायरेक्ट्री में सेट करता है, ताकि जनरेट किया गया सोर्स ढूंढा जा सके. हालांकि, पहले बताई गई वजहों से, प्लैटफ़ॉर्म कोड में इस तरीके का इस्तेमाल सिर्फ़ तब करना चाहिए, जब ज़रूरी हो.
इससे C/C++ और मिलती-जुलती भाषाओं में कोई समस्या नहीं होती, क्योंकि जनरेट किए गए सोर्स का पाथ सीधे कंपाइलर को दिया जाता है. ↩
include!
, टेक्स्ट को शामिल करके काम करता है. इसलिए, यह नेमस्पेस में मौजूद वैल्यू का रेफ़रंस दे सकता है, नेमस्पेस में बदलाव कर सकता है या#![foo]
जैसे कंस्ट्रक्ट का इस्तेमाल कर सकता है. इन छिपे हुए इंटरैक्शन को बनाए रखना मुश्किल हो सकता है. जब क्रेट के बाकी हिस्सों के साथ इंटरैक्ट करना ज़रूरी हो, तो हमेशा मैक्रो का इस्तेमाल करें. ↩