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

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

Xcode और Bazel में अंतर

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

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

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

  • बिल्ड कॉन्फ़िगरेशन स्कीमा, जैसे कि डायरेक्ट्री लेआउट या बिल्ड फ़्लैग में अंतर होने की वजह से, हो सकता है कि Xcode को बिल्ड की "बड़ी फ़ोटो" के बारे में पूरी जानकारी न हो. इसलिए, हो सकता है कि Xcode की कुछ सुविधाएं काम न करें. इनके नाम हैं:

    • Tulsi में कन्वर्ज़न के लिए आपने जो टारगेट चुने हैं उनके आधार पर, हो सकता है कि Xcode सही तरीके से प्रोजेक्ट के सोर्स को इंडेक्स न कर पाए. इसका असर Xcode में कोड पूरा होने और उस पर नेविगेट करने पर पड़ता है, क्योंकि Xcode को प्रोजेक्ट के सभी सोर्स कोड नहीं दिखेंगे.

    • स्टैटिक विश्लेषण, ऐड्रेस सैनिटाइज़र, और थ्रेड सैनिटाइज़र शायद काम न करें, क्योंकि हो सकता है कि Bazel ऐसे आउटपुट न दे पाए जो Xcode से उन सुविधाओं के लिए चाहिए.

    • अगर आपने Tulsi के साथ Xcode प्रोजेक्ट जनरेट किया और Xcode में जांच शुरू करने के लिए उस प्रोजेक्ट का इस्तेमाल किया, तो Bazel के बजाय Xcode जांच करेगा. Bazel से टेस्ट करने के लिए, bazel test कमांड को मैन्युअल तरीके से चलाएं.

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

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

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

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

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

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

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

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

Bazel के साथ Xcode प्रोजेक्ट बनाएं या टेस्ट करें

Bazel के साथ Xcode प्रोजेक्ट बनाने या टेस्ट करने के लिए, ये काम करें:

  1. WORKSPACE फ़ाइल बनाएं

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

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

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

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

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

  4. (ज़रूरी नहीं) बिल्ड को बड़े पैमाने पर बनाएं

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

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

पहला चरण: WORKSPACE फ़ाइल बनाना

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

दूसरा चरण: (प्रयोग के तौर पर) CocoaPods की डिपेंडेंसी इंटिग्रेट करना

CocoaPods डिपेंडेंसी को Bazel फ़ाइल फ़ोल्डर में इंटिग्रेट करने के लिए, आपको उन्हें Bazel पैकेज में बदलना होगा. इस बारे में, CocoaPods डिपेंडेंसी बदलना लेख में बताया गया है.

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

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

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

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

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

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

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

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

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

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

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

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

  • macos_unit_test की मदद से, macOS पर लाइब्रेरी-आधारित और ऐप्लिकेशन-आधारित यूनिट टेस्ट किए जा सकते हैं.

  • ios_unit_test का इस्तेमाल iOS पर लाइब्रेरी-आधारित यूनिट टेस्ट करने के लिए करें. iOS सिम्युलेटर की ज़रूरत वाले टेस्ट के लिए, Bazel टेस्ट आउटपुट बनाएगा, लेकिन टेस्ट नहीं करेगा. आपको Tulsi के साथ एक Xcode प्रोजेक्ट जनरेट करना होगा और Xcode में जांच करनी होगी.

  • ios_ui_test का इस्तेमाल ऐसे आउटपुट को बनाने के लिए किया जाता है जो Xcode का इस्तेमाल करके, iOS सिम्युलेटर में यूज़र इंटरफ़ेस टेस्ट चलाने के लिए ज़रूरी होते हैं. आपको Tulsi के साथ एक Xcode प्रोजेक्ट जनरेट करना होगा और Xcode के अंदर से टेस्ट चलाना होगा. Bazel, मूल रूप से यूज़र इंटरफ़ेस (यूआई) की जांच नहीं कर सकता.

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

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

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

लाइब्रेरी टारगेट को इस तरह जोड़ें:

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

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

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

  • hdrs एट्रिब्यूट में हेडर की सूची बनाएं.

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

यहां से बिल्ड की जांच करना अच्छा आइडिया है:

bazel build //:<application_target>

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

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

  • बिल्ड में बढ़ोतरी हुई,

  • बिल्ड टास्क को साथ में लागू करना ज़्यादा किया गया,

  • आने वाले समय में उपयोगकर्ताओं के लिए बेहतर रखरखाव,

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

प्रोजेक्ट को विस्तृत बनाने के लिए सलाह:

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

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

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

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

  • अपने सभी पैकेज देखने के लिए, एक तय सीमा लागू करें.

  • BUILD फ़ाइलों में किए गए हर बड़े बदलाव के बाद प्रोजेक्ट बनाएं और अगर आपको कोई गड़बड़ी मिलती है, तो उसे ठीक करें.

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

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

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

bazel build //:my-target

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

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

समस्या हल करना

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

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

  • सही वर्शन दिखाने के लिए Xcode 'चुनें' का इस्तेमाल करें, लाइसेंस स्वीकार करें, और Bazel की स्थिति मिटाएं.

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