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

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

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

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

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

कॉन्सेप्ट

रिपॉज़िटरी

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

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

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

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

मुख्य रिपॉज़िटरी के रूट को वर्कस्पेस रूट भी कहा जाता है.

Workspace

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

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

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

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

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

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

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

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

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

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

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

अब तक, सबसे सामान्य रिपॉज़िटरी नियम ये हैं: 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 के परिभाषाओं के साथ काम नहीं करता. इसके बजाय, यह मॉड्यूल से डिपेंडेंसी ग्राफ़ बनाता है. साथ ही, ग्राफ़ के ऊपर एक्सटेंशन चलाता है और उसके हिसाब से रिपॉज़िटरी तय करता है.

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

WORKSPACE सिस्टम के लॉन्च होने के बाद से, अब तक लोगों ने कई समस्याओं के बारे में बताया है. जैसे:

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

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