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

समस्या की शिकायत करें सोर्स देखें Nightly · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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, ऐप्लिकेशन को सही एपीआई लेवल के साथ बनाता है.

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

bazel build //:<application_target>

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

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

  • बिल्ड की इंक्रीमेंटैलिटी में बढ़ोतरी,

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

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

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

प्रोजेक्ट को ज़्यादा बारीकी से समझने के लिए सलाह:

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

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

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

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

  • सभी पैकेज के लिए, विज्ञापन दिखने से जुड़ी सीमाएं लागू करें.

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

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

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

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

bazel build //:my-target

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

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

समस्या का हल

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

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

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

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