Android के लिए रस्ट मॉड्यूल

सामान्य सिद्धांत के तौर पर, rust_* मॉड्यूल की परिभाषाएं, cc_* इस्तेमाल और उम्मीदों के मुताबिक होती हैं. यहां Rust बाइनरी के लिए मॉड्यूल की परिभाषा का उदाहरण दिया गया है:

rust_binary {
    name: "hello_rust",
    crate_name: "hello_rust",
    srcs: ["src/hello_rust.rs"],
    host_supported: true,
}

इस पेज पर, rust_* मॉड्यूल की सबसे सामान्य प्रॉपर्टी के बारे में बताया गया है. मॉड्यूल के टाइप और मॉड्यूल की परिभाषाओं के उदाहरणों के बारे में ज़्यादा जानने के लिए, बाइनरी मॉड्यूल, लाइब्रेरी मॉड्यूल या टेस्ट मॉड्यूल देखें.

बेसिक मॉड्यूल टाइप

टाइपपरिभाषाअधिक जानकारी के लिए
rust_binaryRust बाइनरी बाइनरी मॉड्यूल page
rust_libraryयह Rust लाइब्रेरी बनाता है. साथ ही, rlib और dylib, दोनों वैरिएंट उपलब्ध कराता है. rust_library, लाइब्रेरी मॉड्यूल पेज.
rust_ffiयह cc मॉड्यूल के लिए, इस्तेमाल की जा सकने वाली Rust C लाइब्रेरी बनाता है. साथ ही, स्टैटिक और शेयर किए गए दोनों वैरिएंट उपलब्ध कराता है. rust_ffi, लाइब्रेरी मॉड्यूल पेज
rust_proc_macroproc-macro Rust लाइब्रेरी बनाता है. (ये कंपाइलर प्लगिन के जैसे होते हैं.) rust_proc_macro, लाइब्रेरी मॉड्यूल पेज
rust_testयह स्टैंडर्ड Rust टेस्ट हार्नेस का इस्तेमाल करने वाला Rust टेस्ट बाइनरी बनाता है. टेस्ट मॉड्यूल पेज
rust_fuzzयह libfuzzer का इस्तेमाल करके, Rust फ़ज़ बाइनरी बनाता है. rust_fuzz मॉड्यूल का उदाहरण
rust_protobufसोर्स जनरेट करता है और Rust लाइब्रेरी बनाता है. यह लाइब्रेरी, किसी खास protobuf के लिए इंटरफ़ेस उपलब्ध कराती है. Protobufs Modules और Source Generators पेज
rust_bindgenयह सोर्स जनरेट करता है और Rust लाइब्रेरी बनाता है. इस लाइब्रेरी में, C लाइब्रेरी के लिए Rust बाइंडिंग होती हैं. Bindgen Bindings Modules और Source Generators पेज

सामान्य तौर पर इस्तेमाल होने वाली ज़रूरी प्रॉपर्टी

ये प्रॉपर्टी, सभी Android Rust मॉड्यूल में एक जैसी होती हैं. अलग-अलग Rust मॉड्यूल से जुड़ी कोई भी अतिरिक्त (यूनीक) प्रॉपर्टी, उस मॉड्यूल के पेज पर दिखती है.

नाम

name आपके मॉड्यूल का नाम है. अन्य Soong मॉड्यूल की तरह, यह भी ज़्यादातर Android.bp मॉड्यूल टाइप में यूनीक होना चाहिए. डिफ़ॉल्ट रूप से, name का इस्तेमाल आउटपुट फ़ाइल के नाम के तौर पर किया जाता है. अगर आउटपुट फ़ाइल का नाम, मॉड्यूल के नाम से अलग होना चाहिए, तो इसे तय करने के लिए stem प्रॉपर्टी का इस्तेमाल करें.

स्टेम

stem (ज़रूरी नहीं) की मदद से, आउटपुट फ़ाइल के नाम को सीधे तौर पर कंट्रोल किया जा सकता है. इसमें फ़ाइल एक्सटेंशन और अन्य सफ़िक्स शामिल नहीं हैं. उदाहरण के लिए, rust_library_rlib स्टेम वैल्यू libfoo वाली लाइब्रेरी से libfoo.rlib फ़ाइल जनरेट होती है. अगर आपने stem प्रॉपर्टी के लिए कोई वैल्यू नहीं दी है, तो आउटपुट फ़ाइल का नाम डिफ़ॉल्ट रूप से मॉड्यूल के नाम पर सेट हो जाता है.

अगर आपको मॉड्यूल का नाम, आउटपुट फ़ाइल के नाम के तौर पर सेट करने में समस्या आ रही है, तो stem फ़ंक्शन का इस्तेमाल करें. उदाहरण के लिए, log क्रेट के लिए rust_library का नाम liblog_rust है, क्योंकि liblog cc_library पहले से मौजूद है. इस मामले में, stem प्रॉपर्टी का इस्तेमाल करने से यह पक्का होता है कि आउटपुट फ़ाइल का नाम liblog_rust.* के बजाय liblog.* है.

srcs

srcs में एक सोर्स फ़ाइल होती है, जो आपके मॉड्यूल के एंट्री पॉइंट को दिखाती है. आम तौर पर, यह main.rs या lib.rs होती है. rustc, कंपाइल करने के लिए ज़रूरी अन्य सभी सोर्स फ़ाइलों को रिज़ॉल्व करने और खोजने का काम करता है. ये फ़ाइलें, जनरेट होने वाली deps फ़ाइल में शामिल होती हैं.

जब संभव हो, तो प्लैटफ़ॉर्म कोड के लिए इसका इस्तेमाल न करें. ज़्यादा जानकारी के लिए, सोर्स जनरेटर देखें.

crate_name

crate_name --crate_name फ़्लैग के ज़रिए, क्रेट के नाम का मेटाडेटा सेट करता है.rustc लाइब्रेरी बनाने वाले मॉड्यूल के लिए, यह ज़रूरी है कि यह सोर्स में इस्तेमाल किए गए, अनुमानित क्रेट के नाम से मेल खाए. उदाहरण के लिए, अगर सोर्स में मॉड्यूल libfoo_bar को extern crate foo_bar के तौर पर रेफ़रंस दिया गया है, तो यह ज़रूरी है कि crate_name: "foo_bar" हो.

यह प्रॉपर्टी, सभी rust_* मॉड्यूल के लिए सामान्य है. हालांकि, Rust लाइब्रेरी बनाने वाले मॉड्यूल के लिए, यह ज़रूरी है. जैसे, rust_library rust_ffi, rust_bindgen, rust_protobuf, और rust_proc_macro. ये मॉड्यूल, crate_name और आउटपुट फ़ाइल के नाम के बीच के संबंध पर rustc की ज़रूरी शर्तें लागू करते हैं. ज़्यादा जानकारी के लिए, लाइब्रेरी मॉड्यूल सेक्शन देखें.

लिंट

rustc linter, सोर्स जनरेटर को छोड़कर सभी मॉड्यूल टाइप के लिए डिफ़ॉल्ट रूप से चलता है. कुछ लिंट सेट तय किए जाते हैं और इनका इस्तेमाल, मॉड्यूल सोर्स की पुष्टि करने के लिए किया जाता है. इस तरह के लिंट सेट के लिए, ये वैल्यू हो सकती हैं:

  • default मॉड्यूल की जगह के हिसाब से, डिफ़ॉल्ट रूप से सेट किए गए लिंट
  • android सबसे सख्त लिंट सेट, जो सभी Android प्लैटफ़ॉर्म कोड पर लागू होता है
  • vendor वेंडर कोड पर लागू किए गए लिंट का एक आसान सेट
  • none का इस्तेमाल करके, लिंट की सभी चेतावनियों और गड़बड़ियों को अनदेखा करें

clippy_lints

clippy linter को भी डिफ़ॉल्ट रूप से सभी मॉड्यूल टाइप के लिए चलाया जाता है. हालांकि, सोर्स जनरेटर के लिए इसे नहीं चलाया जाता. कुछ लिंट सेट तय किए गए हैं. इनका इस्तेमाल, मॉड्यूल सोर्स की पुष्टि करने के लिए किया जाता है. यहां कुछ संभावित वैल्यू दी गई हैं:

  • default मॉड्यूल की जगह के हिसाब से, डिफ़ॉल्ट रूप से सेट किए गए लिंट
  • android सबसे सख्त लिंट सेट, जो सभी Android प्लैटफ़ॉर्म कोड पर लागू होता है
  • vendor वेंडर कोड पर लागू किए गए लिंट का एक आसान सेट
  • none का इस्तेमाल करके, लिंट की सभी चेतावनियों और गड़बड़ियों को अनदेखा करें

वर्शन

edition इस कोड को कंपाइल करने के लिए, इस्तेमाल किए जाने वाले Rust वर्शन को तय करता है. यह C और C++ के std वर्शन जैसा ही है. मान्य वैल्यू 2015, 2018, और 2021 (डिफ़ॉल्ट) हैं.

फ़्लैग

flags में, फ़्लैग की स्ट्रिंग सूची होती है. इन्हें कंपाइल करने के दौरान rustc को पास किया जाता है.

ld_flags

ld-flags में, सोर्स को कंपाइल करते समय लिंकर को पास किए जाने वाले फ़्लैग की स्ट्रिंग सूची होती है. इन्हें -C linker-args rustc फ़्लैग से पास किया जाता है. clang का इस्तेमाल लिंकर के फ़्रंट-एंड के तौर पर किया जाता है. यह lld को लिंक करने के लिए शुरू करता है.

सुविधाएं

features, सुविधाओं की एक स्ट्रिंग सूची है. इन्हें कंपाइल करने के दौरान चालू करना ज़रूरी है. इसे --cfg 'feature="foo"', rustc को पास करता है. ज़्यादातर सुविधाएं ऐड-ऑन होती हैं. इसलिए, कई मामलों में इसमें उन सभी सुविधाओं का पूरा सेट शामिल होता है जिनकी ज़रूरत सभी डिपेंडेंट मॉड्यूल को होती है. हालांकि, अगर कोई सुविधा किसी दूसरी सुविधा से अलग है, तो ऐसी बिल्ड फ़ाइलों में अतिरिक्त मॉड्यूल तय करें जिनमें एक-दूसरे से अलग सुविधाएं दी गई हैं.

cfgs

cfgs में, cfg फ़्लैग की स्ट्रिंग सूची होती है. इन्हें कंपाइल करने के दौरान चालू किया जाता है. इसे --cfg foo और --cfg "fizz=buzz", rustc को पास करते हैं.

बिल्ड सिस्टम, कुछ खास स्थितियों में अपने-आप cfg फ़्लैग सेट करता है. इन स्थितियों के बारे में यहां बताया गया है:

  • डाइनैमिक लाइब्रेरी (डिलिब) के तौर पर बनाए गए मॉड्यूल में, android_dylib cfg सेट होगा.

  • जिन मॉड्यूल को वीएनडीके का इस्तेमाल करना है उनके लिए, android_vndk cfg सेट किया जाएगा. यह C++ के लिए __ANDROID_VNDK__ की परिभाषा के जैसा ही है.

स्ट्रिप

strip यह कंट्रोल करता है कि आउटपुट फ़ाइल को हटाया जाए या नहीं. अगर हटाया जाता है, तो कैसे हटाया जाए. अगर इस नीति को सेट नहीं किया जाता है, तो डिवाइस मॉड्यूल डिफ़ॉल्ट रूप से मिनी डिबग जानकारी को छोड़कर बाकी सभी जानकारी हटा देते हैं. होस्ट मॉड्यूल, डिफ़ॉल्ट रूप से किसी भी सिंबल को नहीं हटाते. मान्य वैल्यू में ये शामिल हैं: none, जिससे स्ट्रिपिंग बंद हो जाती है. साथ ही, all, जिससे मिनी डिबग जानकारी के साथ-साथ सब कुछ स्ट्रिप हो जाता है. अन्य वैल्यू, Soong Modules Reference में देखी जा सकती हैं.

host_supported

डिवाइस मॉड्यूल के लिए, host_supported पैरामीटर यह बताता है कि मॉड्यूल को होस्ट वैरिएंट भी उपलब्ध कराना चाहिए या नहीं.

लाइब्रेरी डिपेंडेंसी तय करना

Rust मॉड्यूल, इन प्रॉपर्टी की मदद से CC और Rust लाइब्रेरी, दोनों पर निर्भर हो सकते हैं:

प्रॉपर्टी का नाम ब्यौरा
rustlibs rust_library मॉड्यूल की सूची, जो डिपेंडेंसी भी हैं. डिपेंडेंसी का एलान करने के लिए, इसे अपने पसंदीदा तरीके के तौर पर इस्तेमाल करें. इससे बिल्ड सिस्टम को पसंदीदा लिंकेज चुनने की अनुमति मिलती है. (नीचे Rust लाइब्रेरी से लिंक करने के बारे में जानकारी देखें)
rlibs rust_library के उन मॉड्यूल की सूची जिन्हें rlibs के तौर पर स्टैटिक रूप से लिंक किया जाना चाहिए. (इसका इस्तेमाल सावधानी से करें; नीचे Rust लाइब्रेरी से लिंक करते समय जानकारी देखें.)
shared_libs cc_library मॉड्यूल की सूची, जिन्हें शेयर की गई लाइब्रेरी के तौर पर डाइनैमिक तरीके से लिंक किया जाना चाहिए.
static_libs cc_library मॉड्यूल की सूची, जिन्हें स्टैटिक लाइब्रेरी के तौर पर स्टैटिक रूप से लिंक किया जाना चाहिए.
whole_static_libs cc_library मॉड्यूल की सूची, जिन्हें स्टैटिक लाइब्रेरी के तौर पर स्टैटिक रूप से लिंक किया जाना चाहिए. साथ ही, इन्हें पूरी तरह से नतीजे वाली लाइब्रेरी में शामिल किया जाना चाहिए. rust_ffi_static वैरिएंट के लिए, whole_static_libraries को स्टैटिक लाइब्रेरी के संग्रह में शामिल किया जाएगा. rust_library_rlib के अलग-अलग वर्शन के लिए, whole_static_libraries लाइब्रेरी को rlib लाइब्रेरी में बंडल किया जाएगा.

Rust लाइब्रेरी से लिंक करते समय, सबसे सही तरीका यह है कि rlibs या dylibs के बजाय rustlibs प्रॉपर्टी का इस्तेमाल करें. ऐसा तब तक करें, जब तक आपके पास ऐसा करने की कोई खास वजह न हो. इससे बिल्ड सिस्टम, रूट मॉड्यूल की ज़रूरत के हिसाब से सही लिंक चुन पाता है. साथ ही, इससे इस बात की संभावना कम हो जाती है कि डिपेंडेंसी ट्री में किसी लाइब्रेरी के rlib और dylib, दोनों वर्शन शामिल हों. ऐसा होने पर, कंपाइलेशन पूरा नहीं हो पाएगा.

ऐसी सुविधाएं जो बिल्ड के साथ काम नहीं करती हैं और जो सीमित तौर पर काम करती हैं

Soong's Rust, vendor और vendor_ramdisk इमेज और स्नैपशॉट के लिए सीमित सहायता उपलब्ध कराता है. हालांकि, staticlibs, cdylibs, rlibs, और binaries काम करते हैं. वेंडर इमेज बिल्ड टारगेट के लिए, android_vndk cfg प्रॉपर्टी सेट की जाती है. अगर सिस्टम और वेंडर के टारगेट में अंतर है, तो कोड में इसका इस्तेमाल किया जा सकता है. rust_proc_macros वेंडर स्नैपशॉट के हिस्से के तौर पर कैप्चर नहीं किए जाते हैं. अगर ये ज़रूरी हैं, तो पक्का करें कि आपने इन्हें सही तरीके से वर्शन-कंट्रोल किया हो.

प्रॉडक्ट, VNDK, और रिकवरी इमेज के लिए यह सुविधा उपलब्ध नहीं है.

इंक्रीमेंटल बिल्ड

डेवलपर, SOONG_RUSTC_INCREMENTAL एनवायरमेंट वैरिएबल को true पर सेट करके, Rust सोर्स के इंक्रीमेंटल कंपाइलेशन को चालू कर सकते हैं.

चेतावनी: इस बात की कोई गारंटी नहीं है कि इससे जनरेट किए गए बाइनरी, बिल्डबॉट से जनरेट किए गए बाइनरी के जैसे ही होंगे. ऑब्जेक्ट फ़ाइलों में मौजूद फ़ंक्शन या डेटा के पते अलग-अलग हो सकते हैं. यह पक्का करने के लिए कि जनरेट किए गए आर्टफ़ैक्ट, EngProd के इन्फ़्रास्ट्रक्चर से बनाए गए आर्टफ़ैक्ट से 100% मेल खाते हों, इस वैल्यू को सेट न करें.