एक्सटर्नल डिपेंडेंसी के बारे में खास जानकारी

समस्या की शिकायत करें सोर्स देखें

Bazel आपके बिल्ड में इस्तेमाल की जाने वाली बाहरी डिपेंडेंसी, ऐसी सोर्स फ़ाइलें (टेक्स्ट और बाइनरी दोनों) काम करता है जो आपके फ़ाइल फ़ोल्डर में नहीं हैं. उदाहरण के लिए, वे GitHub के रेपो में होस्ट किए गए नियम, मेवन आर्टफ़ैक्ट या आपके मौजूदा फ़ाइल फ़ोल्डर के बाहर आपकी लोकल मशीन पर मौजूद डायरेक्ट्री हो सकते हैं.

Bazel 6.0 के बाद से, बाहरी डिपेंडेंसी मैनेज करने के दो तरीके हैं: Bazel के साथ बाहरी डिपेंडेंसी मैनेज करने के लिए:WORKSPACEWORKSPACEMODULE.bazel--enable_bzlmod

यह दस्तावेज़, Bazel में बाहरी डिपेंडेंसी मैनेजमेंट से जुड़े कॉन्सेप्ट के बारे में बताता है. इसके बाद, दोनों सिस्टम के बारे में ज़्यादा जानकारी देता है.

कॉन्सेप्ट

रिपॉज़िटरी

WORKSPACE या WORKSPACE.bazel फ़ाइल वाली डायरेक्ट्री. इसमें ऐसी सोर्स फ़ाइलें शामिल होंगी जिन्हें Bazel बिल्ड में इस्तेमाल किया जाएगा. अक्सर इसे छोटा करके सिर्फ़ रिपो किया जाता है.

मुख्य डेटा स्टोर करने की जगह

वह रिपॉज़िटरी (डेटा स्टोर करने की जगह), जिसमें मौजूदा Bazel कमांड चल रहा है.

फ़ाइल फ़ोल्डर

सभी Bazel कमांड के साथ शेयर किया जाने वाला एनवायरमेंट, एक ही मुख्य रिपॉज़िटरी में चलता है.

ध्यान दें कि पुराने समय से "डेटा स्टोर करने की जगह" और "फ़ाइल फ़ोल्डर" के सिद्धांत आपस में मिलते-जुलते रहे हैं. "वर्कस्पेस" शब्द का इस्तेमाल, अक्सर मुख्य डेटा स्टोर करने के लिए किया जाता है. कभी-कभी इसे "डेटा स्टोर करने की जगह" के समान भी इस्तेमाल किया जाता है.

कैननिकल डेटा स्टोर करने की जगह का नाम

वह कैननिकल नाम, जिससे डेटा स्टोर किया जा सकता है. किसी फ़ाइल फ़ोल्डर के संदर्भ में, हर रिपॉज़िटरी का एक कैननिकल नाम होता है. रेपो में मौजूद टारगेट का कैननिकल नाम canonical_name है. इसे @@canonical_name//pac/kage:target लेबल से पता किया जा सकता है (डबल @ पर ध्यान दें).

मुख्य डेटा स्टोर करने की जगह में कैननिकल नाम के तौर पर हमेशा खाली स्ट्रिंग होती है.

डेटा स्टोर करने की जगह का साफ़ तौर पर दिखने वाला नाम

वह नाम जिसे किसी डेटा स्टोर करने की जगह के तौर पर पता किया जा सकता है. इसे रेपो का "निकनेम" माना जा सकता है: michael के कैननिकल नाम वाले रेपो का नाम mike हो सकता है, जो रेपो के संदर्भ में हो alice. हालांकि, रेपो के हिसाब से इसमें साफ़ तौर पर दिखने वाला नाम mickey हो सकता है bob. इस मामले में, michael के अंदर के टारगेट को alice के संदर्भ में @mike//pac/kage:target लेबल से पता किया जा सकता है. हालांकि, @ को ध्यान में रखें.

इसके उलट, इसे डेटा स्टोर करने की जगह की मैपिंग के तौर पर समझा जा सकता है: हर रिपॉज़िटरी में, "साफ़ तौर पर डेटा स्टोर करने की जगह का नाम" से "कैननिकल डेटा स्टोर करने की जगह के नाम" तक की मैपिंग होती है.

डेटा स्टोर करने की जगह का नियम

रिपॉज़िटरी की परिभाषाओं के लिए स्कीमा, जो Bazel को बताता है कि वह डेटा कैसे स्टोर किया जाएगा. उदाहरण के लिए, "किसी खास यूआरएल से ZIP फ़ॉर्मैट वाला संग्रह डाउनलोड करना" या "किसी खास Maven आर्टफ़ैक्ट को फ़ेच करके उसे java_import के टारगेट के तौर पर उपलब्ध कराना" या "किसी लोकल डायरेक्ट्री को सिमलिंक करना" हो सकता है. हर रेपो को तय किया जाता है. इसके लिए, उचित संख्या में तर्क के साथ रेपो नियम कॉल किया जाता है.

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

डेटा स्टोर करने के सबसे आम नियम हैं: http_archive, जो यूआरएल से संग्रह को डाउनलोड करता है और उसे एक्सट्रैक्ट करता है. local_repository एक लोकल डायरेक्ट्री की सिमलिंक करता है, जो पहले से ही Bazel का डेटा स्टोर करने की जगह है.

डेटा स्टोर करने की जगह को फ़ेच करें

डेटा स्टोर करने की जगह, लोकल डिस्क पर डेटा स्टोर करने की सुविधा से जुड़ा नियम लागू करके, डेटा वापस करने की प्रोसेस को कहते हैं. फ़ाइल फ़ोल्डर में तय किए गए रिपो, फ़ेच किए जाने से पहले लोकल डिस्क पर उपलब्ध नहीं होते.

आम तौर पर, Bazel सिर्फ़ तब रेपो फ़ेच करता है, जब उसे रेपो से कोई ज़रूरत होती है. अगर रेपो को पहले ही फ़ेच कर लिया गया है, तो Bazel उसे सिर्फ़ तब फिर से फ़ेच करता है, जब उसकी परिभाषा बदल गई हो.

डायरेक्ट्री का लेआउट

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

कैननिकल नाम canonical_name के साथ डेटा स्टोर करने की जगह का कॉन्टेंट देखने के लिए, यह निर्देश दिया जा सकता है:

ls $(bazel info output_base)/external/ canonical_name 

Bzlmod की मदद से, बाहरी डिपेंडेंसी मैनेज करें

Bzlmod, नया एक्सटर्नल डिपेंडेंसी सबसिस्टम है. यह रेपो डेफ़िनिशन के साथ सीधे तौर पर काम नहीं करता. इसके बजाय, यह मॉड्यूल से डिपेंडेंसी ग्राफ़ बनाता है, ग्राफ़ के ऊपर एक्सटेंशन चलाता है, और उसी हिसाब से डेटा स्टोर करने की जगह तय करता है.

Bazel मॉड्यूल एक Bazel प्रोजेक्ट है. इसके कई वर्शन हो सकते हैं. इनमें से हर वर्शन, उन दूसरे मॉड्यूल के बारे में मेटाडेटा पब्लिश करता है जिन पर यह निर्भर करता है. मॉड्यूल के रेपो रूट में WORKSPACE फ़ाइल के बगल में, एक MODULE.bazel फ़ाइल होनी चाहिए. यह फ़ाइल, मॉड्यूल की मेनिफ़ेस्ट फ़ाइल है. इसमें, इसके नाम, वर्शन, डिपेंडेंसी की सूची वगैरह के साथ-साथ अन्य जानकारी भी दी जाती है. यह एक बुनियादी उदाहरण है:

module(name = "my-module", version = "1.0")

bazel_dep(name = "rules_cc", version = "0.0.1")
bazel_dep(name = "protobuf", version = "3.19.0")

किसी मॉड्यूल में सिर्फ़ डायरेक्ट डिपेंडेंसी की सूची होनी चाहिए, जिसे Bzlmod, डिफ़ॉल्ट तौर पर Bazel Central Registry में, Bazel रजिस्ट्री में देखता है. यह रजिस्ट्री, डिपेंडेंसी की MODULE.bazel फ़ाइलें उपलब्ध कराती है. इसकी मदद से, Bazel, वर्शन रिज़ॉल्यूशन से पहले, पूरे ट्रांज़िशनिव डिपेंडेंसी ग्राफ़ को खोज पाता है.

वर्शन रिज़ॉल्यूशन के बाद, जिसमें हर मॉड्यूल के लिए एक वर्शन चुना जाता है, बेज़ल हर मॉड्यूल के लिए रिपो को तय करने का तरीका जानने के लिए, रजिस्ट्री से फिर से सलाह लेते हैं (ज़्यादातर मामलों में, http_archive का इस्तेमाल करके).

मॉड्यूल, डेटा के कस्टमाइज़ किए गए हिस्सों के बारे में भी बता सकते हैं. इन्हें टैग कहते हैं. इन्हें मॉड्यूल एक्सटेंशन, मॉड्यूल रिज़ॉल्यूशन के बाद इस्तेमाल किया जाता है. इससे, डेटा स्टोर करने की अतिरिक्त जगह तय की जाती है. इन एक्सटेंशन में रीपो नियमों जैसी क्षमताएं होती हैं, जो उन्हें फ़ाइल I/O और नेटवर्क अनुरोध भेजने जैसी कार्रवाइयां करने में सक्षम बनाते हैं. साथ ही, इसकी मदद से Bazel, दूसरे पैकेज मैनेजमेंट सिस्टम से इंटरैक्ट कर पाता है. साथ ही, वह Bazel मॉड्यूल से बने डिपेंडेंसी ग्राफ़ का भी पालन करता है.

WORKSPACE की मदद से डेटा स्टोर करने की जगह तय करें

अब तक, आपके पास WORKSPACE (या WORKSPACE.bazel) फ़ाइल में डेटा स्टोर करने की जगह तय करके, बाहरी डिपेंडेंसी मैनेज करने का विकल्प होता है. इस फ़ाइल का सिंटैक्स BUILD फ़ाइलों से मिलता-जुलता है, जिसमें बिल्ड के नियम के बजाय रेपो नियमों का इस्तेमाल किया जाता है.

नीचे दिया गया स्निपेट, WORKSPACE फ़ाइल में http_archive रेपो नियम का इस्तेमाल करने का एक उदाहरण है:

load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
    name = "foo",
    urls = ["https://example.com/foo.zip"],
    sha256 = "c9526390a7cd420fdcec2988b4f3626fe9c5b51e2959f685e8f4d170d1a9bd96",
)

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

WORKSPACE सिस्टम की कमियां

WORKSPACE सिस्टम के आने के बाद से, उपयोगकर्ताओं ने कई समस्याओं की शिकायत की है, जैसे:

  • Bazel किसी भी डिपेंडेंसी की WORKSPACE फ़ाइल का आकलन नहीं करता है. इसलिए, सीधे तौर पर होने वाली डिपेंडेंसी के अलावा, सभी ट्रांज़िशन डिपेंडेंसी की जानकारी, मुख्य डेटा स्टोर करने की WORKSPACE फ़ाइल में दी जानी चाहिए.
  • इस पर काम करने के लिए, प्रोजेक्ट ने "deps.bzl" पैटर्न अपनाया है. इसमें एक मैक्रो तय किया गया है, जो कई रिपो को तय करता है. साथ ही, उपयोगकर्ताओं को अपनी WORKSPACE फ़ाइल में इस मैक्रो को कॉल करने के लिए कहते हैं.
    • इसमें कुछ समस्याएं हैं: मैक्रो अन्य .bzl फ़ाइलों को load नहीं कर सकते. इसलिए, इन प्रोजेक्ट को इस "डेप" मैक्रो में अपनी ट्रांज़िटिव डिपेंडेंसी तय करनी होती है या उपयोगकर्ता को कई लेयर वाले "deps" मैक्रो को कॉल करके इस समस्या को हल करना होता है.
    • Bazel, WORKSPACE फ़ाइल का क्रम से आकलन करता है. इसके अलावा, किसी भी वर्शन की जानकारी के बिना, यूआरएल के साथ http_archive का इस्तेमाल करके डिपेंडेंसी बताई जाती हैं. इसका मतलब है कि डायमंड डिपेंडेंसी के मामले में, वर्शन रिज़ॉल्यूशन करने का कोई भरोसेमंद तरीका नहीं है. A, B और C पर निर्भर करता है. B और C, दोनों D के अलग-अलग वर्शन पर निर्भर करते हैं.

Workspace की कमियों की वजह से, आने वाले समय में Bazel की रिलीज़ में, Bzlmod, Workspace के लेगसी सिस्टम की जगह लेगा. Bzlmod पर माइग्रेट करने का तरीका जानने के लिए, कृपया Bzlmod माइग्रेशन गाइड पढ़ें.