Xcode से Bazel पर माइग्रेट करना

इस पेज पर, Bazel की मदद से Xcode प्रोजेक्ट बनाने या उसकी जांच करने का तरीका बताया गया है. इसमें Xcode और Bazel के बीच के अंतर के बारे में बताया गया है. साथ ही, Xcode प्रोजेक्ट को Bazel प्रोजेक्ट में बदलने का तरीका भी बताया गया है. इसमें, आम तौर पर होने वाली गड़बड़ियों को ठीक करने के तरीके भी बताए गए हैं.

Xcode और Bazel के बीच के अंतर

  • Bazel में, आपको हर बिल्ड टारगेट और उसकी डिपेंडेंसी के साथ-साथ, बिल्ड के नियमों के ज़रिए बिल्ड की सेटिंग साफ़ तौर पर बतानी होती हैं.

  • Bazel के लिए, प्रोजेक्ट से जुड़ी सभी फ़ाइलें, वर्कस्पेस डायरेक्ट्री में मौजूद होनी चाहिए. इसके अलावा, उन्हें MODULE.bazel फ़ाइल में डिपेंडेंसी के तौर पर बताया जाना चाहिए.

  • Bazel की मदद से Xcode प्रोजेक्ट बनाते समय, BUILD फ़ाइलें, सोर्स ऑफ़ ट्रुथ बन जाती हैं. अगर Xcode में प्रोजेक्ट पर काम किया जाता है, तो BUILD फ़ाइलों को अपडेट करने पर, आपको Xcode प्रोजेक्ट का नया वर्शन जनरेट करना होगा. यह वर्शन, rules_xcodeproj का इस्तेमाल करके BUILD फ़ाइलों से मेल खाना चाहिए. BUILD फ़ाइलों में कुछ बदलाव करने पर, प्रोजेक्ट को फिर से जनरेट करने की ज़रूरत नहीं होती. जैसे, किसी टारगेट में डिपेंडेंसी जोड़ना. इससे डेवलपमेंट की प्रोसेस तेज़ हो सकती है. अगर Xcode का इस्तेमाल नहीं किया जा रहा है, तो bazel build और bazel test कमांड, बिल्ड और टेस्ट की सुविधाएं देती हैं. हालांकि, इनकी कुछ सीमाएं हैं. इनके बारे में इस गाइड में आगे बताया गया है.

शुरू करने से पहले

शुरू करने से पहले, यह काम करें:

  1. अगर आपने Bazel को पहले से इंस्टॉल नहीं किया है, तो उसे इंस्टॉल करें.

  2. अगर आपको Bazel और उसके कॉन्सेप्ट के बारे में जानकारी नहीं है, तो iOS ऐप्लिकेशन ट्यूटोरियल पूरा करें. आपको Bazel के वर्कस्पेस के बारे में जानकारी होनी चाहिए. इसमें MODULE.bazel और BUILD फ़ाइलें शामिल हैं. साथ ही, आपको टारगेट, बिल्ड के नियम, और Bazel पैकेज के कॉन्सेप्ट के बारे में भी जानकारी होनी चाहिए.

  3. प्रोजेक्ट की डिपेंडेंसी का विश्लेषण करें और उन्हें समझें.

प्रोजेक्ट की डिपेंडेंसी का विश्लेषण करना

Xcode के उलट, Bazel में आपको BUILD फ़ाइल में हर टारगेट के लिए सभी डिपेंडेंसी साफ़ तौर पर बतानी होती हैं.

बाहरी डिपेंडेंसी के बारे में ज़्यादा जानने के लिए, बाहरी डिपेंडेंसी के साथ काम करना लेख पढ़ें.

Bazel की मदद से Xcode प्रोजेक्ट बनाना या उसकी जांच करना

Bazel की मदद से Xcode प्रोजेक्ट बनाने या उसकी जांच करने के लिए, यह तरीका अपनाएं:

  1. MODULE.bazel फ़ाइल बनाना

  2. (एक्सपेरिमेंटल) SwiftPM डिपेंडेंसी इंटिग्रेट करना

  3. BUILD फ़ाइल बनाना:

    a. ऐप्लिकेशन टारगेट जोड़ना

    b. (ज़रूरी नहीं) टेस्ट टारगेट जोड़ना

    c. लाइब्रेरी टारगेट जोड़ना

  4. (ज़रूरी नहीं) बिल्ड को अलग-अलग हिस्सों में बांटना

  5. बिल्ड चलाना

  6. rules_xcodeproj की मदद से Xcode प्रोजेक्ट जनरेट करना

पहला चरण: MODULE.bazel फ़ाइल बनाना

नई डायरेक्ट्री में MODULE.bazel फ़ाइल बनाएं. यह डायरेक्ट्री, Bazel के वर्कस्पेस की रूट डायरेक्ट्री बन जाती है. अगर प्रोजेक्ट में कोई बाहरी डिपेंडेंसी इस्तेमाल नहीं की जाती है, तो यह फ़ाइल खाली हो सकती है. अगर प्रोजेक्ट, ऐसी फ़ाइलों या पैकेज पर निर्भर करता है जो प्रोजेक्ट की किसी डायरेक्ट्री में नहीं हैं, तो MODULE.bazel फ़ाइल में इन बाहरी डिपेंडेंसी के बारे में बताएं.

दूसरा चरण: (एक्सपेरिमेंटल) SwiftPM डिपेंडेंसी इंटिग्रेट करना

swift_bazel

तीसरा चरण: BUILD फ़ाइल बनाना

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

अहम जानकारी: पैकेज और Bazel के अन्य कॉन्सेप्ट के बारे में ज़्यादा जानने के लिए, वर्कस्पेस, पैकेज, और टारगेट लेख पढ़ें.

तीसरा चरण (a): ऐप्लिकेशन टारगेट जोड़ना

macos_application या ios_application नियम टारगेट जोड़ें. इस टारगेट से, macOS या iOS ऐप्लिकेशन बंडल बनता है. टारगेट में, कम से कम ये चीज़ें तय करें:

  • bundle_id - बाइनरी का बंडल आईडी (रिवर्स-डीएनएस पाथ, जिसके बाद ऐप्लिकेशन का नाम लिखा हो) .

  • provisioning_profile - Apple Developer खाते से प्रोविज़निंग प्रोफ़ाइल (अगर iOS डिवाइस के लिए बिल्ड किया जा रहा है).

  • families (सिर्फ़ iOS के लिए) - ऐप्लिकेशन को iPhone, iPad या दोनों के लिए बिल्ड करना है.

  • infoplists - .plist फ़ाइलों की सूची, जिन्हें फ़ाइनल Info.plist फ़ाइल में मर्ज करना है.

  • minimum_os_version - macOS या iOS का वह कम से कम वर्शन जिस पर ऐप्लिकेशन काम करता है. इससे यह पक्का होता है कि Bazel, ऐप्लिकेशन को सही एपीआई लेवल के साथ बिल्ड करे.

तीसरा चरण (b): (ज़रूरी नहीं) टेस्ट टारगेट जोड़ना

Bazel के Apple बिल्ड नियम, Apple के सभी प्लैटफ़ॉर्म पर यूनिट और यूज़र इंटरफ़ेस (यूआई) टेस्ट चलाने की सुविधा देते हैं. टेस्ट टारगेट जोड़ने के लिए, यह तरीका अपनाएं:

  • macos_unit_test macOS पर, लाइब्रेरी और ऐप्लिकेशन पर आधारित यूनिट टेस्ट चलाने के लिए, जोड़ें.

  • ios_unit_test iOS पर, लाइब्रेरी पर आधारित यूनिट टेस्ट बनाने और चलाने के लिए, जोड़ें.

  • ios_ui_test iOS सिम्युलेटर में, यूज़र इंटरफ़ेस टेस्ट बनाने और चलाने के लिए, जोड़ें.

  • tvOS, watchOS and visionOS के लिए भी इसी तरह के टेस्ट के नियम मौजूद हैं.

कम से कम, minimum_os_version एट्रिब्यूट के लिए कोई वैल्यू तय करें. पैकेजिंग के अन्य एट्रिब्यूट, जैसे कि bundle_identifier और infoplists के लिए, आम तौर पर इस्तेमाल की जाने वाली वैल्यू डिफ़ॉल्ट तौर पर सेट होती हैं. हालांकि, यह पक्का करें कि ये डिफ़ॉल्ट वैल्यू, प्रोजेक्ट के साथ काम करती हों. साथ ही, ज़रूरत के हिसाब से इनमें बदलाव करें. ऐसे टेस्ट के लिए जिनमें iOS सिम्युलेटर की ज़रूरत होती है, ios_application टारगेट का नाम, test_host एट्रिब्यूट की वैल्यू के तौर पर भी तय करें.

तीसरा चरण(c): लाइब्रेरी टारगेट जोड़ना

हर Objective-C लाइब्रेरी के लिए objc_library टारगेट और हर Swift लाइब्रेरी के लिए swift_library टारगेट जोड़ें. ऐप्लिकेशन और/या टेस्ट, इन लाइब्रेरी पर निर्भर करते हैं.

लाइब्रेरी टारगेट जोड़ने के लिए, यह तरीका अपनाएं:

  • ऐप्लिकेशन लाइब्रेरी टारगेट को, ऐप्लिकेशन टारगेट में डिपेंडेंसी के तौर पर जोड़ें.

  • टेस्ट लाइब्रेरी टारगेट को, टेस्ट टारगेट में डिपेंडेंसी के तौर पर जोड़ें.

  • srcs एट्रिब्यूट में, लागू करने के सोर्स की सूची जोड़ें.

  • hdrs एट्रिब्यूट में, हेडर की सूची जोड़ें.

अलग-अलग तरह के ऐप्लिकेशन के लिए, मौजूदा उदाहरणों को rules_apple के उदाहरणों वाली डायरेक्ट्री में जाकर सीधे तौर पर देखा जा सकता है. उदाहरण के लिए:

बिल्ड के नियमों के बारे में ज़्यादा जानने के लिए, Bazel के लिए Apple के नियम लेख पढ़ें.

इस चरण पर, बिल्ड की जांच करना अच्छा होता है:

bazel build //:<application_target>

चौथा चरण: (ज़रूरी नहीं) बिल्ड को अलग-अलग हिस्सों में बांटना

अगर प्रोजेक्ट बड़ा है या वह बढ़ रहा है, तो उसे Bazel के कई पैकेज में बांटने पर विचार करें. बिल्ड को अलग-अलग हिस्सों में बांटने से ये फ़ायदे मिलते हैं:

  • बिल्ड को इंक्रीमेंटल तरीके से बनाने की सुविधा मिलती है,

  • बिल्ड के टास्क को एक साथ चलाने की सुविधा मिलती है,

  • भविष्य में उपयोगकर्ताओं के लिए, रखरखाव बेहतर तरीके से किया जा सकता है,

  • टारगेट और पैकेज में, सोर्स कोड की विज़िबिलिटी को बेहतर तरीके से कंट्रोल किया जा सकता है. इससे, ऐसी समस्याएं नहीं होतीं जैसे कि लाइब्रेरी में लागू करने से जुड़ी जानकारी, सार्वजनिक एपीआई में लीक हो जाती है.

प्रोजेक्ट को अलग-अलग हिस्सों में बांटने के लिए सुझाव:

  • हर लाइब्रेरी को, Bazel के अलग-अलग पैकेज में रखें. उन लाइब्रेरी से शुरुआत करें जिनके लिए कम से कम डिपेंडेंसी की ज़रूरत होती है. इसके बाद, डिपेंडेंसी ट्री में आगे बढ़ें.

  • BUILD फ़ाइलें जोड़ते समय और टारगेट तय करते समय, इन नए टारगेट को उन टारगेट के deps एट्रिब्यूट में जोड़ें जो इन पर निर्भर करते हैं.

  • glob() फ़ंक्शन, पैकेज की सीमाओं को पार नहीं करता. इसलिए, पैकेज की संख्या बढ़ने पर, glob() से मैच होने वाली फ़ाइलें कम हो जाएंगी.

  • main डायरेक्ट्री में BUILD फ़ाइल जोड़ते समय, उससे जुड़ी test डायरेक्ट्री में भी BUILD फ़ाइल जोड़ें.

  • पैकेज में, विज़िबिलिटी की सीमाओं को लागू करें.

  • BUILD फ़ाइलों में हर बड़े बदलाव के बाद, प्रोजेक्ट को बिल्ड करें. साथ ही, बिल्ड में होने वाली गड़बड़ियों को ठीक करें.

पांचवा चरण: बिल्ड चलाना

पूरी तरह से माइग्रेट किए गए बिल्ड को चलाएं, ताकि यह पक्का किया जा सके कि यह बिना किसी गड़बड़ी या चेतावनी के पूरा हो. किसी भी गड़बड़ी के सोर्स को आसानी से ढूंढने के लिए, हर ऐप्लिकेशन और टेस्ट टारगेट को अलग-अलग चलाएं.

उदाहरण के लिए:

bazel build //:my-target

छठा चरण: rules_xcodeproj की मदद से Xcode प्रोजेक्ट जनरेट करना

Bazel की मदद से बिल्ड करते समय, MODULE.bazel और BUILD फ़ाइलें, बिल्ड के बारे में सोर्स ऑफ़ ट्रुथ बन जाती हैं. Xcode को इस बारे में बताने के लिए, आपको Bazel के साथ काम करने वाला Xcode प्रोजेक्ट जनरेट करना होगा. इसके लिए, rules_xcodeproj का इस्तेमाल करें.

समस्या का हल

Bazel में गड़बड़ियां तब हो सकती हैं, जब वह चुने गए Xcode वर्शन के साथ सिंक नहीं होता. जैसे, अपडेट लागू करने पर. अगर आपको Xcode में गड़बड़ियां आ रही हैं, तो ये तरीके आज़माएं. उदाहरण के लिए, "Apple CROSSTOOL का इस्तेमाल करने के लिए, Xcode का वर्शन तय करना ज़रूरी है".

  • Xcode को मैन्युअल तरीके से चलाएं और सभी नियमों और शर्तों को स्वीकार करें.

  • सही वर्शन बताने, लाइसेंस स्वीकार करने, और Bazel की स्थिति साफ़ करने के लिए, Xcode select का इस्तेमाल करें.

  sudo xcode-select -s /Applications/Xcode.app/Contents/Developer
  sudo xcodebuild -license
  bazel sync --configure
  • अगर इससे समस्या ठीक नहीं होती है, तो bazel clean --expunge चलाकर देखें.