निंजा (एक्सपेरिमेंट के तौर पर उपलब्ध) का इस्तेमाल करके, कस्टम C/C++ बिल्ड सिस्टम इंटिग्रेट करें

अगर CMake या ndk-build का इस्तेमाल नहीं किया जा रहा है, लेकिन आपको 'Android Gradle प्लग इन (AGP)' C/C++ बिल्ड और Android Studio का पूरा इंटिग्रेशन चाहिए, तो कस्टम C/C++ बिल्ड सिस्टम बनाया जा सकता है. इसके लिए, आपको एक शेल स्क्रिप्ट बनानी होगी. यह स्क्रिप्ट Ninja की बिल्ड फ़ाइल फ़ॉर्मैट में बिल्ड की जानकारी के तौर पर मौजूद होगी.

Android Studio और AGP में कस्टम C/C++ बिल्ड सिस्टम के लिए एक्सपेरिमेंट के तौर पर उपलब्ध सहायता जोड़ी गई है. यह सुविधा Android Studio डॉल्फ़िन | 3.1 कैनरी 4.

खास जानकारी

C/C++ प्रोजेक्ट, खास तौर पर वे प्रोजेक्ट जो एक से ज़्यादा प्लैटफ़ॉर्म को टारगेट करते हैं, का एक सामान्य पैटर्न, उन प्लैटफ़ॉर्म के लिए प्रोजेक्ट जनरेट करना होता है. इस पैटर्न का एक खास उदाहरण CMake है. CMake की मदद से Android, iOS, और दूसरे प्लैटफ़ॉर्म के लिए प्रोजेक्ट जनरेट किए जा सकते हैं. यह प्रोजेक्ट, CMakeLists.txt फ़ाइल में सेव किए गए एक ही प्रज़ेंटेशन से किया जा सकता है.

CMake की सुविधा AGP के साथ सीधे तौर पर काम करती है. इसके बावजूद, कुछ ऐसे प्रोजेक्ट जनरेटर उपलब्ध हैं जो सीधे तौर पर काम नहीं करते:

इस तरह के प्रोजेक्ट जनरेटर, निंजा के साथ C/C++ बिल्ड के बैकएंड रिप्रज़ेंटेशन के साथ काम करते हैं या इन्हें बैकएंड प्रज़ेंटेशन के तौर पर निंजा जनरेट करने के लिए इस्तेमाल किया जा सकता है.

सही तरीके से कॉन्फ़िगर किए जाने पर, इंटिग्रेट किए गए C/C++ प्रोजेक्ट सिस्टम जनरेटर वाले AGP प्रोजेक्ट की मदद से, उपयोगकर्ता ये काम कर सकते हैं:

  • कमांड-लाइन और Android Studio की मदद से बनाया गया ऐप्लिकेशन.

  • Android Studio में जाकर, उन सोर्स में बदलाव करें जिनमें भाषा से जुड़ी सभी सुविधाएं उपलब्ध हैं. जैसे, किसी एक कीवर्ड की परिभाषा.

  • नेटिव और मिक्स प्रोसेस को डीबग करने के लिए, Android Studio डीबगर का इस्तेमाल करें.

कस्टम C/C++ बिल्ड कॉन्फ़िगरेशन स्क्रिप्ट का इस्तेमाल करने के लिए, अपने बिल्ड में बदलाव करने का तरीका

इस सेक्शन में, एजीपी की कस्टम C/C++ बिल्ड कॉन्फ़िगरेशन स्क्रिप्ट इस्तेमाल करने का तरीका बताया गया है.

पहला चरण: कॉन्फ़िगरेशन स्क्रिप्ट का रेफ़रंस देने के लिए, मॉड्यूल-लेवल की build.gradle फ़ाइल में बदलाव करें

एजीपी में निंजा से जुड़ी सहायता चालू करने के लिए, मॉड्यूल-लेवल की build.gradle फ़ाइल में experimentalProperties को कॉन्फ़िगर करें:

android {
  defaultConfig {
    externalNativeBuild {
      experimentalProperties["ninja.abiFilters"] = [ "x86", "arm64-v8a" ]
      experimentalProperties["ninja.path"] = "source-file-list.txt"
      experimentalProperties["ninja.configure"] = "configure-ninja"
      experimentalProperties["ninja.arguments"] = [
            "\${ndk.moduleMakeFile}",
            "--variant=\${ndk.variantName}",
            "--abi=Android-\${ndk.abi}",
            "--configuration-dir=\${ndk.configurationDir}",
            "--ndk-version=\${ndk.moduleNdkVersion}",
            "--min-sdk-version=\${ndk.minSdkVersion}"
       ]
     }
   }

एजीपी ने प्रॉपर्टी की व्याख्या इस तरह की है:

  • ninja.abiFilters, एबीआई की एक सूची है, जिसे बनाया जाना है. मान्य वैल्यू ये हैं: x86, x86-64, armeabi-v7a, और arm64-v8a.

  • ninja.path, किसी C/C++ प्रोजेक्ट फ़ाइल का पाथ है. इस फ़ाइल का फ़ॉर्मैट अपनी पसंद के हिसाब से कुछ भी हो सकता है. इस फ़ाइल में बदलाव करने पर, Android Studio में Gradle सिंक के लिए सूचना ट्रिगर होगी.

  • ninja.configure, स्क्रिप्ट फ़ाइल का पाथ है, जिसे Gradle से तब एक्ज़ीक्यूट किया जाएगा, जब C/C++ प्रोजेक्ट को कॉन्फ़िगर करना ज़रूरी होगा. किसी प्रोजेक्ट को Android Studio में ग्रेडल के सिंक होने के दौरान या पहले बिल्ड पर कॉन्फ़िगर किया जाता है. ऐसा तब भी किया जाता है, जब कॉन्फ़िगर करने के लिए इस्तेमाल होने वाली किसी स्क्रिप्ट में बदलाव होता है.

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

    • ninja.configure फ़ाइल का पूरा पाथ ${ndk.moduleMakeFile} है. इसलिए, उदाहरण में, यह C:\path\to\configure-ninja.bat होगा.

    • बनाए जा रहे मौजूदा एजीपी वैरिएंट का नाम ${ndk.variantName} है. उदाहरण के लिए, डीबग या रिलीज़ करना.

    • ${ndk.abi}, मौजूदा एजीपी एबीआई का नाम है, जो बनाया जा रहा है. उदाहरण के लिए, x86 या arm64-v8a.

    • ${ndk.buildRoot}, एक ऐसे फ़ोल्डर का नाम होता है जिसे AGP जनरेट करता है. इस पर स्क्रिप्ट अपना आउटपुट लिखती है. इसके बारे में जानकारी दूसरा चरण: कॉन्फ़िगर स्क्रिप्ट बनाएं में दी गई है.

    • ${ndk.ndkVersion}, इस्तेमाल किए जाने वाले एनडीके का वर्शन है. आम तौर पर, यह वैल्यू build.gradle फ़ाइल में android.ndkVersion को पास की जाती है. इसके अलावा, अगर कोई वैल्यू मौजूद नहीं है, तो यह डिफ़ॉल्ट वैल्यू होती है.

    • एजीपी की ओर से अनुरोध किया गया कम से कम टारगेट Android प्लैटफ़ॉर्म ${ndk.minPlatform} है.

  • ninja.targets उन निंजा टारगेट की सूची है जिन्हें बनाया जाना चाहिए.

दूसरा चरण: कॉन्फ़िगर करने वाली स्क्रिप्ट बनाएं

कॉन्फ़िगर स्क्रिप्ट (पिछले उदाहरण में configure-ninja.bat) की सबसे कम ज़िम्मेदारी एक build.ninja फ़ाइल जनरेट करना है, जो निंजा के साथ बनाए जाने पर, प्रोजेक्ट के सभी नेटिव आउटपुट को कंपाइल और लिंक करेगी. आम तौर पर, ये .o (ऑब्जेक्ट), .a (संग्रह) और .so (शेयर किए गए ऑब्जेक्ट) फ़ाइलें होती हैं.

आपकी ज़रूरतों के मुताबिक, कॉन्फ़िगर स्क्रिप्ट build.ninja फ़ाइल को दो अलग-अलग जगहों पर लिख सकता है.

  • अगर AGP के लिए जगह चुनना सही है, तो कॉन्फ़िगर करने वाली स्क्रिप्ट, ${ndk.buildRoot} मैक्रो में सेट की गई जगह पर build.ninja लिखती है.

  • अगर कॉन्फ़िगर स्क्रिप्ट को build.ninja फ़ाइल की जगह चुननी है, तो वह ${ndk.buildRoot} मैक्रो में सेट की गई जगह पर, build.ninja.txt नाम की एक फ़ाइल भी लिखती है. इस फ़ाइल में build.ninja फ़ाइल का पूरा पाथ शामिल है, जिसे कॉन्फ़िगर करने वाली स्क्रिप्ट ने लिखा है.

build.ninja फ़ाइल का स्ट्रक्चर

आम तौर पर, Android C/C++ बिल्ड को सटीक तरीके से दिखाने वाली ज़्यादातर स्ट्रक्चर काम करेंगे. AGP और Android Studio के लिए, ये मुख्य बातें ज़रूरी हैं:

  • C/C++ सोर्स फ़ाइलों की सूची और Clang को इकट्ठा करने के लिए ज़रूरी फ़्लैग.

  • आउटपुट लाइब्रेरी की सूची. आम तौर पर, ये .so (शेयर किए गए ऑब्जेक्ट) फ़ाइलें होती हैं. हालांकि, ये .a (संग्रह) या एक्ज़ीक्यूटेबल (कोई एक्सटेंशन नहीं) भी हो सकती हैं.

अगर आपको build.ninja फ़ाइल जनरेट करने के उदाहरण चाहिए, तो build.ninja जनरेटर का इस्तेमाल करने पर CMake का आउटपुट देखें.

यहां कम से कम build.ninja टेंप्लेट का एक उदाहरण दिया गया है.

rule COMPILE
   command = /path/to/ndk/clang -c $in -o $out {other flags}
rule LINK
   command = /path/to/ndk/clang $in -o $out {other flags}

build source.o : COMPILE source.cpp
build lib.so : LINK source.o

सबसे सही तरीके

ज़रूरी शर्तों (सोर्स फ़ाइलों और आउटपुट लाइब्रेरी की सूची) के अलावा, यहां सुझाए गए कुछ सबसे सही तरीके बताए गए हैं.

phony नियमों की मदद से, नाम वाले आउटपुट का एलान करें

हमारा सुझाव है कि जब भी मुमकिन हो, build.ninja स्ट्रक्चर में phony नियमों का इस्तेमाल करें, ताकि बिल्ड आउटपुट में ऐसे नाम दिए जा सकें जिन्हें कोई भी व्यक्ति आसानी से पढ़ सके. उदाहरण के लिए, अगर आपके पास c:/path/to/lib.so नाम का आउटपुट है, तो इस तरह से उसे कोई ऐसा नाम दें जिसे कोई भी व्यक्ति आसानी से पढ़ सके.

build curl: phony /path/to/lib.so

ऐसा करने का फ़ायदा यह है कि build.gradle फ़ाइल में इस नाम को बिल्ड टारगेट के तौर पर तय किया जा सकता है. उदाहरण के लिए,

android {
  defaultConfig {
    externalNativeBuild {
      ...
      experimentalProperties["ninja.targets"] = [ "curl" ]

'सभी' चुनें टारगेट

जब all के लिए टारगेट तय किया जाता है, तो यह एजीपी की बनाई लाइब्रेरी का डिफ़ॉल्ट सेट होगा. ऐसा तब होगा, जब build.gradle फ़ाइल में साफ़ तौर पर कोई टारगेट तय नहीं किया गया हो.

rule COMPILE
   command = /path/to/ndk/clang $in -o $out {other flags}
rule LINK
   command = /path/to/ndk/clang $in -o $out {other flags}

build foo.o : COMPILE foo.cpp
build bar.o : COMPILE bar.cpp
build libfoo.so : LINK foo.o
build libbar.so : LINK bar.o
build all: phony libfoo.so libbar.so

बिल्ड का कोई दूसरा तरीका बताएं (ज़रूरी नहीं)

इस्तेमाल का बेहतर उदाहरण, ऐसे मौजूदा बिल्ड सिस्टम को रैप करना है जो निंजा पर आधारित नहीं है. इस मामले में, आपको अब भी आउटपुट लाइब्रेरी के साथ-साथ सभी सोर्स को उनके फ़्लैग के साथ दिखाना होगा. इससे Android Studio, ऑटोकंप्लीट और गो-टू डेफ़िनिशन जैसी भाषा से जुड़ी सेवा की सही सुविधाएं दिखा पाएगा. हालांकि, आपको बिल्ड सिस्टम के हिसाब से एजीपी की मदद लेनी होगी.

ऐसा करने के लिए, खास एक्सटेंशन .passthrough के साथ निंजा बिल्ड आउटपुट का इस्तेमाल किया जा सकता है.

एक बेहतर उदाहरण के तौर पर, मान लें कि आपको MSBuild के साथ रैप करना है. आपकी कॉन्फ़िगर स्क्रिप्ट हमेशा की तरह build.ninja जनरेट करेगी. हालांकि, यह एक पासथ्रू टारगेट भी जोड़ेगी जो यह तय करता है कि एजीपी, MSBuild को कैसे शुरू करेगा.

rule COMPILE
   command = /path/to/ndk/clang $in -o $out {other flags}
rule LINK
   command = /path/to/ndk/clang $in -o $out {other flags}

rule MBSUILD_CURL
  command = /path/to/msbuild {flags to build curl with MSBuild}

build source.o : COMPILE source.cpp
build lib.so : LINK source.o
build curl : phony lib.so
build curl.passthrough : MBSUILD_CURL

सुझाव, शिकायत या राय दें

इस सुविधा को अभी आज़माया जा रहा है. इसलिए, हमें आपके सुझाव, शिकायत या राय के लिए धन्यवाद. इन तरीकों से सुझाव/राय दी जा सकती है या शिकायत की जा सकती है:

  • सामान्य सुझाव के लिए इस गड़बड़ी पर टिप्पणी करें.

  • किसी गड़बड़ी की शिकायत करने के लिए, Android Studio खोलें. इसके बाद, सहायता > शिकायत, सुझाव या राय सबमिट करें. "कस्टम C/C++ बिल्ड सिस्टम" को ज़रूर देखें का इस्तेमाल करें.

  • अगर आपके पास Android Studio इंस्टॉल नहीं है, तो गड़बड़ी की शिकायत करने के लिए, इस टेंप्लेट का इस्तेमाल करके गड़बड़ी की शिकायत करें.