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

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

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

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

मॉड्यूल के बुनियादी टाइप

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

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

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

नाम

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

तना

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

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

srcs

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

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

crate_name

crate_name फ़्लैग के ज़रिए, crate के नाम का मेटाडेटा सेट करता है.rustc --crate_name लाइब्रेरी बनाने वाले मॉड्यूल के लिए, यह ज़रूरी है कि यह सोर्स में इस्तेमाल किए गए, crate के नाम से मेल खाए. उदाहरण के लिए, अगर सोर्स में 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 की ज़रूरी शर्तें लागू करते हैं. ज़्यादा जानकारी के लिए, लाइब्रेरी मॉड्यूल सेक्शन देखें.

lints

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

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

clippy_lints

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

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

वर्शन

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 फ़्लैग की स्ट्रिंग सूची शामिल होती है. इसे rustc की मदद से, --cfg foo और --cfg "fizz=buzz" को पास किया जाता है.

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

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

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

पट्टी

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

host_supported

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

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

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

प्रॉपर्टी का नाम ब्यौरा
rustlibs rust_library मॉड्यूल की सूची. ये मॉड्यूल, डिपेंडेंसी भी हैं. डिपेंडेंसी के बारे में बताने के लिए, इस तरीके का इस्तेमाल करें. इससे बिल्ड सिस्टम को पसंदीदा लिंकिंग चुनने में मदद मिलती है. (नीचे, Rust लाइब्रेरी के ख़िलाफ़ लिंक करना देखें)
rlibs rust_library मॉड्यूल की सूची. इन्हें स्टैटिक तौर पर लिंक किया जाना चाहिए as 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 का Rust, vendor और vendor_ramdisk इमेज और स्नैपशॉट के लिए सीमित सहायता उपलब्ध कराता है. हालांकि, staticlibs, cdylibs, rlibs, और binaries के लिए सहायता उपलब्ध है. वेंडर इमेज के बिल्ड टारगेट के लिए, android_vndk cfg प्रॉपर्टी सेट की जाती है. अगर सिस्टम और वेंडर टारगेट के बीच अंतर है, तो इसका इस्तेमाल कोड में किया जा सकता है. rust_proc_macros को वेंडर स्नैपशॉट के हिस्से के तौर पर कैप्चर नहीं किया जाता. अगर ये स्नैपशॉट, डिपेंडेंसी के तौर पर इस्तेमाल किए जाते हैं, तो पक्का करें कि आपने इन्हें सही तरीके से वर्शन कंट्रोल किया हो.

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

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

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

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