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

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

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

Bazel 6.0 के बाद, Bazel की मदद से बाहरी डिपेंडेंसी मैनेज करने के दो तरीके हैं: पहला, रिपॉज़िटरी पर फ़ोकस करने वाला पारंपरिक WORKSPACE सिस्टम और दूसरा, मॉड्यूल पर फ़ोकस करने वाला नया MODULE.bazel सिस्टम (इसका कोडनेम Bzlmod है और इसे फ़्लैग --enable_bzlmod की मदद से चालू किया जाता है). इन दोनों सिस्टम का एक साथ इस्तेमाल किया जा सकता है. हालांकि, Bazel के आने वाले रिलीज़ में Bzlmod, WORKSPACE सिस्टम की जगह ले लेगा. माइग्रेट करने का तरीका जानने के लिए, Bzlmod माइग्रेशन गाइड देखें.

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

कॉन्सेप्ट

रिपॉज़िटरी

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

रिपॉज़िटरी के बाउंड्री मार्कर की फ़ाइल, MODULE.bazel (इससे पता चलता है कि यह रिपॉज़िटरी, Bazel मॉड्यूल को दिखाती है), REPO.bazel (यहां देखें) या लेगसी कॉन्टेक्स्ट में, WORKSPACE या WORKSPACE.bazel हो सकती है. किसी भी रिपॉज़िटरी की सीमा को मार्क करने वाली फ़ाइल, रिपॉज़िटरी की सीमा को दिखाएगी. एक डायरेक्ट्री में ऐसी कई फ़ाइलें एक साथ मौजूद हो सकती हैं.

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

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

डेटा स्टोर करने की मुख्य जगह के रूट को फ़ाइल फ़ोल्डर रूट भी कहा जाता है.

Workspace

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

किसी भी बिल्ड को पूरा करने के लिए, रिपॉज़िटरी, टारगेट या सभी ज़रूरी रिपॉज़िटरी के लिए प्री-फ़ेच शुरू करने के लिए fetch कमांड का इस्तेमाल किया जा सकता है. इस सुविधा की मदद से, --nofetch विकल्प का इस्तेमाल करके ऑफ़लाइन बिल्ड चालू किए जा सकते हैं.

--fetch विकल्प, नेटवर्क ऐक्सेस को मैनेज करने के लिए इस्तेमाल किया जाता है. इसकी डिफ़ॉल्ट वैल्यू 'सही' होती है. हालांकि, अगर 'गलत' (--nofetch) पर सेट किया जाता है, तो निर्देश, डिपेंडेंसी के कैश मेमोरी में सेव किए गए किसी भी वर्शन का इस्तेमाल करेगा. अगर कोई वर्शन मौजूद नहीं है, तो निर्देश काम नहीं करेगा.

फ़ेच को कंट्रोल करने के बारे में ज़्यादा जानकारी के लिए, फ़ेच करने के विकल्प देखें.

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

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

कैननिकल नाम canonical_name वाले रिपॉज़िटरी का कॉन्टेंट देखने के लिए, यह कमांड चलाएं:

ls $(bazel info output_base)/external/ canonical_name 

REPO.bazel फ़ाइल

REPO.bazel फ़ाइल का इस्तेमाल, उस डायरेक्ट्री ट्री की सबसे ऊपरी सीमा को मार्क करने के लिए किया जाता है जिससे कोई रिपॉज़िटरी बनता है. रीपो के बाउंड्री फ़ाइल के तौर पर काम करने के लिए, इसमें कुछ भी शामिल करने की ज़रूरत नहीं है. हालांकि, इसका इस्तेमाल रीपो में मौजूद सभी बिल्ड टारगेट के लिए कुछ सामान्य एट्रिब्यूट तय करने के लिए भी किया जा सकता है.

REPO.bazel फ़ाइल का सिंटैक्स, BUILD फ़ाइलों से मिलता-जुलता है. हालांकि, इसमें load स्टेटमेंट काम नहीं करते. साथ ही, इसमें सिर्फ़ एक फ़ंक्शन, repo() उपलब्ध है. repo(), BUILD फ़ाइलों में package() फ़ंक्शन के जैसे ही आर्ग्युमेंट लेता है. हालांकि, package() पैकेज में मौजूद सभी बिल्ड टारगेट के लिए सामान्य एट्रिब्यूट तय करता है, जबकि repo() इसी तरह, रिपॉज़िटरी में मौजूद सभी बिल्ड टारगेट के लिए ऐसा करता है.

उदाहरण के लिए, अपने रिपॉज़िटरी में मौजूद सभी टारगेट के लिए एक ही लाइसेंस तय किया जा सकता है. इसके लिए, नीचे दी गई REPO.bazel फ़ाइल का इस्तेमाल करें:

repo(
    default_package_metadata = ["//:my_license"],
)

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

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

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

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

मॉड्यूल में, टैग नाम के डेटा के कस्टमाइज़ किए गए हिस्सों की जानकारी भी दी जा सकती है. मॉड्यूल रिज़ॉल्यूशन के बाद, मॉड्यूल एक्सटेंशन इनका इस्तेमाल करते हैं, ताकि अन्य रिपॉज़िटरी तय की जा सकें. इन एक्सटेंशन में, repo के नियमों जैसी सुविधाएं होती हैं. इनकी मदद से, फ़ाइल 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 सिस्टम की कमियां

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 पर माइग्रेट करने के लिए बनी गाइड पढ़ें.