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

किसी समस्या की शिकायत करें सोर्स देखें Nightly · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

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

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

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

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

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

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

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

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

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

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

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

  1. अगर आपने पहले से 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 डिपेंडेंसी इंटिग्रेट करना

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

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

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

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

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

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

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

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

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

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

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

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

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

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

  • 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 टारगेट का नाम भी बताएं.

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

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

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

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

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

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

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

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

इस समय, बने हुए वर्शन की जांच करना अच्छा रहेगा:

bazel build //:<application_target>

चौथा चरण: (ज़रूरी नहीं) बाइनरी को ज़्यादा सटीक बनाना

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

  • बाइनरी के इंक्रीमेंट में बढ़ोतरी,

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

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

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

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

  • हर लाइब्रेरी को उसके अपने Bazel पैकेज में डालें. सबसे कम डिपेंडेंसी वाले डिपेंडेंसी ट्री से शुरू करें और ऊपर की ओर बढ़ें.

  • 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 को मैन्युअल तरीके से चलाएं और सभी नियम और शर्तें स्वीकार करें.

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

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