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

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

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

Basel 6.0 के साथ, बाहरी डिपेंडेंसी को मैनेज करने के दो तरीके हैं: BazeWORKSPACEWORKSPACEMODULE.bazelBzlmod--enable_bzlmod

यह दस्तावेज़, Baज़ल में एक्सटर्नल डिपेंडेंसी मैनेजमेंट से जुड़े सिद्धांतों के बारे में बताता है, ताकि दोनों सिस्टम के बारे में ज़्यादा जानकारी हासिल की जा सके.

कॉन्सेप्ट

रिपॉज़िटरी

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

मुख्य रिपॉज़िटरी

वह रिपॉज़िटरी जिसमें मौजूदा Bazel कमांड चलाया जा रहा है.

Workspace

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

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

कैननिकल रिपॉज़िटरी का नाम

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

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

रिपॉज़िटरी का नाम

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

इसके उलट, इसे रिपॉज़िटरी मैपिंग के तौर पर समझा जा सकता है: हर रिपॉज़िटरी, "रिपॉज़िटरी का दिखने वाला नाम" से "रिपॉज़िटरी का कैननिकल नाम" तक मैपिंग बनाए रखती है.

रिपॉज़िटरी का नियम

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

खुद के रिपॉज़िटरी नियम लिखने के तरीके के बारे में ज़्यादा जानने के लिए, रिपॉज़िटरी के नियम देखें.

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

कोई रिपॉज़िटरी फ़ेच करना

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

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

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

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

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

ls $(bazel info output_base)/external/ canonical_name 

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

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

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 फ़ॉर्मैट में Bagel रजिस्ट्री में ढूंढता है — डिफ़ॉल्ट रूप से, Bazu Central Registry. रजिस्ट्री, डिपेंडेंसी की MODULE.bazel फ़ाइलें उपलब्ध कराती है. इससे Bazel को वर्शन रिज़ॉल्यूशन करने से पहले, ट्रांज़िटिव डिपेंडेंसी ग्राफ़ को पूरा खोजने में मदद मिलती है.

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

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

WORKSPACE की मदद से, रीपॉज़िट के बारे में बताना

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

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

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

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