Bazel आपके एक्सटेंशन में इस्तेमाल की गई बाहरी डिपेंडेंसी, सोर्स फ़ाइलों (टेक्स्ट और बाइनरी, दोनों) के साथ काम करता है. ये फ़ाइलें आपके फ़ाइल फ़ोल्डर से नहीं मिलती हैं. उदाहरण के लिए, वे GitHub repo में होस्ट किए गए एक नियम, Maven आर्टफ़ैक्ट या आपके मौजूदा फ़ाइल फ़ोल्डर के बाहर, आपकी लोकल मशीन पर डायरेक्ट्री हो सकते हैं.
Bazel 6.0 के तहत, Bazel की मदद से बाहरी डिपेंडेंसी को मैनेज किया जा सकता है:
रिपॉज़िटरी (डेटा स्टोर करने की जगह) पर फ़ोकस करने वाला WORKSPACE
सिस्टम और
नए मॉड्यूल पर आधारित MODULE.bazel
सिस्टम (कोड में Bzlmod
और फ़्लैग --enable_bzlmod
के साथ चालू). दोनों सिस्टम एक साथ इस्तेमाल किए जा सकते हैं, लेकिन Bzlmod को WORKSPACE
सिस्टम की जगह, आने वाले रिलीज़ की जगह इस्तेमाल करना होगा.
इस लेख में, दोनों सिस्टम के बारे में ज़्यादा जानकारी देने से पहले, बेज़ल में बाहरी डिपेंडेंसी मैनेजमेंट से जुड़े सिद्धांतों के बारे में बताया गया है.
कॉन्सेप्ट
रिपॉज़िटरी
WORKSPACE
या WORKSPACE.bazel
फ़ाइल वाली डायरेक्ट्री, जिसमें बेज़ल बिल्ड में इस्तेमाल की जाने वाली सोर्स
फ़ाइलें होती हैं. इसे अक्सर repo के तौर पर छोटा किया जाता है.
डेटा स्टोर करने की मुख्य जगह
वह रिपॉज़िटरी जिसमें मौजूदा Bazel कमांड चलाया जा रहा है.
फ़ाइल फ़ोल्डर
Bazel के सभी निर्देशों की मदद से शेयर किया गया एनवायरमेंट, एक ही मुख्य डेटा स्टोर करने की जगह में चलता है.
ध्यान दें कि अब तक "रिपॉज़िटरी" और "फ़ाइल फ़ोल्डर" के कॉन्सेप्ट को एक-दूसरे से बदल दिया गया है. "फ़ाइल फ़ोल्डर" शब्द का इस्तेमाल, अक्सर मुख्य डेटा स्टोर करने की जगह के बारे में बताने के लिए किया जाता है. कभी-कभी, इसे "रिपॉज़िटरी" के मतलब के तौर पर भी इस्तेमाल किया जाता है.
कैननिकल डेटा स्टोर करने की जगह का नाम
डेटा स्टोर करने के कैननिकल यूआरएल का पता किस तरह है. फ़ाइल फ़ोल्डर के संदर्भ में, हर डेटा स्टोर करने की जगह के लिए एक ही कैननिकल नाम होता है. रेपो के अंदर का टारगेट
जिसका कैननिकल नाम canonical_name
है उसे लेबल की मदद से दिखाया जा सकता है
@@canonical_name//pac/kage:target
(डबल @
वैल्यू डालें).
मुख्य रिपॉज़िटरी में हमेशा कैननिकल स्ट्रिंग के तौर पर खाली स्ट्रिंग होती है.
डेटा स्टोर करने की जगह का साफ़-साफ़ दिखने वाला नाम
रिपॉज़िटरी का नाम ऐसा होता है जिसे किसी अन्य डेटा स्टोर पेज के रेफ़रंस में जोड़ा जा सकता है.
इसे रेपो के "निकनेम" के तौर पर देखा जा सकता है: कैननिकल नाम वाले रेपो के रेफ़रंस michael
में रेपो के रेफ़रंस के तौर पर mike
का नाम साफ़ तौर पर दिख सकता है. हालांकि, रेपो के संदर्भ में mickey
का नाम साफ़ तौर पर दिख सकता है.bob
. इस मामले में, michael
के अंदर के टारगेट को alice
के संदर्भ में लेबल
@mike//pac/kage:target
से टारगेट किया जा सकता है (सिर्फ़ @
).
इसके उलट, इसे रिपॉज़िटरी मैपिंग के तौर पर समझा जा सकता है: हर रेपो में "अश्लील रेपो नाम" से "कैननिकल रेपो नाम" तक मैपिंग होती है.
रिपॉज़िटरी नियम
डेटा स्टोर करने की जगह के लिए स्कीमा, जो बैज़ल को डेटा स्टोर करने का तरीका बताने का काम करता है. उदाहरण के लिए, हो सकता है कि वह "किसी खास यूआरएल से ज़िप फ़ॉर्मैट को डाउनलोड करे और उसे निकाले" या "किसी खास Maven आर्टफ़ैक्ट को फ़ेच करे और उसे java_import
टारगेट के तौर पर उपलब्ध कराए." इसके अलावा, उस फ़ाइल में, "किसी स्थानीय डायरेक्ट्री को सिम्युलेट" भी किया जा सकता है. हर रेपो
को तय किया जाता है. इसके लिए रेपो नियम को ज़रूरी संख्या में आर्ग्युमेंट के साथ कॉल किया जाता है.
डेटा स्टोर करने की जगह के अपने नियम लिखने के तरीके के बारे में ज़्यादा जानकारी के लिए, डेटा स्टोर करने की जगह के नियम देखें.
अब तक के सबसे सामान्य रेपो नियम http_archive
हैं, जो किसी यूआरएल से एक संग्रह को डाउनलोड करके उसे निकालते हैं औरlocal_repository
, जो एक स्थानीय निर्देशिका को सिम्युलेट करता है, जो पहले से ही बेज़ल डेटा स्टोर करने की जगह है.
डेटा स्टोर करने की जगह फ़ेच की जा रही है
किसी संबंधित रेपो नियम को चलाकर स्थानीय डिस्क पर डेटा उपलब्ध कराने की प्रक्रिया. फ़ाइल फ़ोल्डर में तय किए गए डेटा को फ़ेच करने से पहले, लोकल डिस्क पर उपलब्ध नहीं होते.
आम तौर पर, बाज़ल किसी रेपो को सिर्फ़ तभी फ़ेच करता है, जब उसे डेटा संग्रह की ज़रूरत होती है और डेटा पहले से नहीं लाया जाता. अगर रेपो को पहले ही फ़ेच कर लिया गया है, तो, बेज़ल इसे सिर्फ़ तब फ़ेच करेगा, जब उसकी परिभाषा बदली गई हो.
डायरेक्ट्री लेआउट
फ़ेच किए जाने के बाद, डेटा को कैननिकल यूआरएल के नीचे, आउटपुट बेस में सबडायरेक्ट्री external
में देखा जा सकता है.
कैननिकल यूआरएल की सामग्री देखने के लिए, यह निर्देश canonical_name
नाम का इस्तेमाल किया जा सकता है:
ls $(bazel info output_base)/external/ canonical_name
Bzlmod के साथ बाहरी डिपेंडेंसी मैनेज करना
Bzlmod, नया बाहरी डिपेंडेंसी सबसिस्टम, सीधे तौर पर परिभाषा के साथ काम नहीं करता. इसके बजाय, यह मॉड्यूल से डिपेंडेंसी ग्राफ़ बनाता है, ग्राफ़ के ऊपर एक्सटेंशन चलाता है, और उसी के मुताबिक डेटा को तय करता है.
बेज़ल मॉड्यूल एक बेज़ल प्रोजेक्ट है, जिसमें कई वर्शन हो सकते हैं. इनमें से हर वर्शन उस मॉड्यूल के बारे में मेटाडेटा प्रकाशित करता है जिस पर वह निर्भर करता है. मॉड्यूल के 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
फ़ाइलें उपलब्ध कराती है. इससे, फ़ाइल का रिज़ॉल्यूशन तय करने से पहले, बैजल को ट्रांज़िशनल डिपेंडेंसी का पूरा ग्राफ़ मिल जाता है.
वर्शन रिज़ॉल्यूशन के बाद, जिसमें हर मॉड्यूल के लिए एक वर्शन चुना जाता है, बेज़ल फिर से रजिस्ट्री की सलाह लेता है, ताकि वह हर मॉड्यूल के लिए रेपो तय करने का तरीका जान सके. (ज़्यादातर मामलों में, http_archive
का इस्तेमाल करके).
मॉड्यूल, टैग नाम के डेटा के कस्टमाइज़ किए गए हिस्से भी तय कर सकते हैं, जिन्हें मॉड्यूल रिज़ॉल्यूशन के बाद मॉड्यूल एक्सटेंशनइस्तेमाल किया जा सकता है, ताकि अतिरिक्त संदर्भ बनाए जा सकें. इन एक्सटेंशन में repo_नियमों के समान क्षमताएं होती हैं. इनकी मदद से, वे फ़ाइल I/O और नेटवर्क अनुरोध भेजने जैसी कार्रवाइयां कर सकते हैं. अन्य चीज़ों के अलावा, वे Bazel को अन्य पैकेज प्रबंधन सिस्टम के साथ इंटरैक्ट करने की अनुमति देते हैं और Bazel मॉड्यूल में बनाए गए डिपेंडेंसी ग्राफ़ का भी सम्मान करते हैं.
Bzlmod पर बाहरी लिंक
- bazelbuild/examples में Bzlmod के इस्तेमाल के उदाहरण
- Bazel बाहरी डिपेंडेंसी ओवरहॉल (मूल Bzlmod डिज़ाइन दस्तावेज़)
- BazelCon 2021 में Bzlmod पर चर्चा
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
फ़ाइलों में इस मैक्रो को कॉल करने के लिए कहा जाता है.- इसकी अपनी समस्याएं हैं: मैक्रो,
load
.bzl
की अन्य फ़ाइलें नहीं बना सकते. इसलिए, इन प्रोजेक्ट में उनकी डिपेंडेंसी डिपेंडेंसी को इस "डेप" मैक्रो में तय करना होता है या उपयोगकर्ता के पास कई लेयर वाले "डेप" मैक्रो कॉल करने का विकल्प होता है. - बेज़ल क्रम से
WORKSPACE
फ़ाइल की जांच करता है. इसके अलावा,http_archive
के आधार पर डिपेंडेंसी, यूआरएल के साथ दी जाती हैं. इसके लिए किसी वर्शन की जानकारी नहीं दी जाती है. इसका मतलब है कि हीरे पर निर्भरता के मामले में वर्शन रिज़ॉल्यूशन काम नहीं करता है (A
,B
औरC
पर निर्भर है;B
औरC
, दोनोंD
के अलग-अलग वर्शन पर निर्भर करते हैं).
- इसकी अपनी समस्याएं हैं: मैक्रो,