अक्सर पूछे जाने वाले सवाल

किसी समस्या की शिकायत करना सोर्स देखना Nightly · 8.2 · 8.1 · 8.0 · 7.6 · 7.5

इस पेज पर, Bazel में बाहरी डिपेंडेंसी के बारे में अक्सर पूछे जाने वाले कुछ सवालों के जवाब दिए गए हैं.

MODULE.bazel

MODULE.bazel में loads क्यों काम नहीं करते?

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

MODULE.bazel में load के लिए पूछने वाले लोगों की दिलचस्पी, आम तौर पर इस्तेमाल के कुछ मामलों में होती है. इन मामलों को load के बिना हल किया जा सकता है:

  • यह पक्का करना कि MODULE.bazel में दिया गया वर्शन, कहीं और सेव किए गए बिल्ड मेटाडेटा से मेल खाता हो. उदाहरण के लिए, .bzl फ़ाइल में: ऐसा करने के लिए, BUILD फ़ाइल से लोड की गई .bzl फ़ाइल में, native.module_version तरीके का इस्तेमाल करें.
  • बहुत बड़ी MODULE.bazel फ़ाइल को मैनेज किए जा सकने वाले सेक्शन में बांटना. ऐसा खास तौर पर, मोनोरेपो के लिए किया जाता है: रूट मॉड्यूल, अपनी MODULE.bazel फ़ाइल को कई सेगमेंट में बांटने के लिए, include डायरेक्टिव का इस्तेमाल कर सकता है. इसी वजह से, हम MODULE.bazel फ़ाइलों में loads की अनुमति नहीं देते. include का इस्तेमाल, नॉन-रूट मॉड्यूल में नहीं किया जा सकता.
  • WORKSPACE के पुराने सिस्टम का इस्तेमाल करने वाले लोगों को याद होगा कि वे किसी रिपॉज़िटरी को एलान करते थे और फिर जटिल लॉजिक लागू करने के लिए, उस रिपॉज़िटरी से तुरंत load करते थे. इस सुविधा को मॉड्यूल एक्सटेंशन से बदल दिया गया है.

क्या किसी bazel_dep के लिए SemVer रेंज तय की जा सकती है?

नहीं. npm और Cargo जैसे कुछ अन्य पैकेज मैनेजर, वर्शन की सीमाओं (अप्रत्यक्ष या साफ़ तौर पर) के साथ काम करते हैं. इसके लिए, अक्सर पाबंदी हल करने वाले टूल की ज़रूरत होती है. इससे, उपयोगकर्ताओं के लिए आउटपुट का अनुमान लगाना मुश्किल हो जाता है. साथ ही, लॉकफ़ाइल के बिना वर्शन रिज़ॉल्यूशन को दोबारा लागू नहीं किया जा सकता.

इसके बजाय, Bazel, Go की तरह कम से कम वर्शन चुनने की सुविधा का इस्तेमाल करता है. इससे, आउटपुट का अनुमान लगाना आसान हो जाता है और फिर से चलाने की गारंटी मिलती है. यह एक ऐसा समझौता है जो Bazel के डिज़ाइन लक्ष्यों से मेल खाता है.

इसके अलावा, Bazel मॉड्यूल के वर्शन, SemVer का सुपरसेट होते हैं. इसलिए, SemVer के सख्त वर्शन में जो सही लगता है वह हमेशा Bazel मॉड्यूल के वर्शन में लागू नहीं होता.

क्या मुझे bazel_dep का नया वर्शन अपने-आप मिल सकता है?

कुछ उपयोगकर्ता कभी-कभी, किसी डिपेंडेंसी का नया वर्शन अपने-आप पाने के लिए, bazel_dep(name = "foo", version = "latest") तय करने की सुविधा के बारे में पूछते हैं. यह SemVer रेंज के बारे में पूछे गए सवाल से मिलता-जुलता है. इसका जवाब भी 'नहीं' है.

हमारा सुझाव है कि आप ऑटोमेशन की मदद से, इस समस्या को हल करें. उदाहरण के लिए, Renovate, Bazel मॉड्यूल के साथ काम करता है.

कभी-कभी, यह सवाल पूछने वाले उपयोगकर्ता, लोकल डेवलपमेंट के दौरान तुरंत बदलाव करने का तरीका खोज रहे होते हैं. ऐसा करने के लिए, local_path_override का इस्तेमाल करें.

ये सभी use_repo क्यों हैं?

MODULE.bazel फ़ाइलों में मॉड्यूल एक्सटेंशन के इस्तेमाल के लिए, कभी-कभी बड़े use_repo निर्देश का इस्तेमाल किया जाता है. उदाहरण के लिए, gazelle से go_deps एक्सटेंशन का सामान्य इस्तेमाल कुछ ऐसा दिख सकता है:

go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//:go.mod")
use_repo(
    go_deps,
    "com_github_gogo_protobuf",
    "com_github_golang_mock",
    "com_github_golang_protobuf",
    "org_golang_x_net",
    ...  # potentially dozens of lines...
)

लंबा use_repo डायरेक्टिव ग़ैर-ज़रूरी लग सकता है, क्योंकि यह जानकारी पहले से ही रेफ़रंस वाली go.mod फ़ाइल में मौजूद है.

Bazel को इस use_repo डायरेक्टिव की ज़रूरत इसलिए होती है, क्योंकि यह मॉड्यूल के एक्सटेंशन को धीरे-धीरे चलाता है. इसका मतलब है कि मॉड्यूल एक्सटेंशन सिर्फ़ तब चलाया जाता है, जब उसका नतीजा देखा जाता है. मॉड्यूल एक्सटेंशन का "आउटपुट", रिपॉज़िटरी की परिभाषाएं होती हैं. इसका मतलब है कि हम किसी मॉड्यूल एक्सटेंशन को सिर्फ़ तब चलाते हैं, जब उसमें बताई गई रिपॉज़िटरी का अनुरोध किया गया हो. उदाहरण के लिए, ऊपर दिए गए उदाहरण में, अगर टारगेट @org_golang_x_net//:foo बनाया गया है. हालांकि, जब तक हम इसे चलाकर नहीं देखते, तब तक हमें नहीं पता कि मॉड्यूल एक्सटेंशन किन रिपॉज़िटरी को तय करेगा. यहां use_repo डायरेक्टिव काम आता है. उपयोगकर्ता, Bazel को बता सकता है कि उसे किन रिपॉज़िटरी से एक्सटेंशन जनरेट करना है. इसके बाद, Bazel सिर्फ़ तब एक्सटेंशन चलाएगा, जब इन रिपॉज़िटरी का इस्तेमाल किया जाएगा.

इस use_repo डायरेक्टिव को बनाए रखने में मदद करने के लिए, मॉड्यूल एक्सटेंशन अपने लागू करने वाले फ़ंक्शन से extension_metadata ऑब्जेक्ट दिखा सकता है. उपयोगकर्ता इन मॉड्यूल एक्सटेंशन के लिए use_repo निर्देशों को अपडेट करने के लिए, bazel mod tidy कमांड चला सकता है.

Bzlmod माइग्रेशन

MODULE.bazel या WORKSPACE, किसका आकलन पहले किया जाता है?

जब --enable_bzlmod और --enable_workspace, दोनों सेट होते हैं, तो यह स्वाभाविक है कि आपके मन में यह सवाल आए कि किस सिस्टम से पहले सलाह ली जाती है. इसका जवाब है कि MODULE.bazel (Bzlmod) का आकलन सबसे पहले किया जाता है.

इसका लंबा जवाब यह है कि "पहले किसका आकलन किया जाता है", यह पूछना सही नहीं है. इसके बजाय, यह पूछना सही होगा: कैननिकल नाम @@foo वाले रिपॉज़िटरी के संदर्भ में, रिपॉज़िटरी का दिखने वाला नाम @bar किस पर लागू होता है? इसके अलावा, @@base की रिपॉज़िटरी मैपिंग क्या है?

साफ़ तौर पर दिखने वाले रिपॉज़िटरी के नाम (एक लीडिंग @) वाले लेबल, संदर्भ के आधार पर अलग-अलग चीज़ों का रेफ़रंस दे सकते हैं. जब आपको कोई लेबल@bar//:baz दिखता है और आपको यह पता नहीं चलता कि वह असल में किस चीज़ पर ले जाता है, तो आपको सबसे पहले यह पता करना होगा कि कॉन्टेक्स्ट रिपॉज़िटरी क्या है: उदाहरण के लिए, अगर लेबल, रिपॉज़िटरी @@foo में मौजूद BUILD फ़ाइल में है, तो कॉन्टेक्स्ट रिपॉज़िटरी @@foo है.

इसके बाद, कॉन्टेक्स्ट रिपॉज़िटरी के हिसाब से, माइग्रेशन गाइड में मौजूद "रिपॉज़िटरी के दिखने की सेटिंग" टेबल का इस्तेमाल करके, यह पता लगाया जा सकता है कि कोई नाम किस रिपॉज़िटरी पर ले जाता है.

  • अगर कॉन्टेक्स्ट रिपॉज़िटरी मुख्य रिपॉज़िटरी (@@) है, तो:
    1. अगर bar, रूट मॉड्यूल की FILE.bazel फ़ाइल के ज़रिए दिखाया गया कोई ऐसा रिपॉज़िटरी नाम है जो bazel_dep, use_repo, module, use_repo_rule में से किसी भी फ़ाइल के ज़रिए दिखाया गया है, तो @bar, FILE.bazel फ़ाइल में बताए गए रिपॉज़िटरी पर ले जाता है.
    2. इसके अलावा, अगर bar, WORKSPACE में तय किया गया कोई रिपॉज़िटरी है (इसका मतलब है कि इसका कैननिकल नाम @@bar है), तो @bar, @@bar पर रीडायरेक्ट करता है.
    3. ऐसा न करने पर, @bar, @@[unknown repo 'bar' requested from @@] जैसा कुछ बन जाएगा और आखिर में गड़बड़ी का मैसेज दिखेगा.
  • अगर कॉन्टेक्स्ट रिपॉज़िटरी, Bzlmod-world रिपॉज़िटरी है (यानी, यह किसी ग़ैर-रूट Bazel मॉड्यूल से जुड़ा है या मॉड्यूल एक्सटेंशन से जनरेट किया गया है), तो इसमें सिर्फ़ Bzlmod-world रिपॉज़िटरी दिखेंगी, न कि WORKSPACE-world रिपॉज़िटरी.
    • खास तौर पर, इसमें रूट मॉड्यूल में non_module_deps जैसे मॉड्यूल एक्सटेंशन में जोड़े गए सभी रिपॉज़िटरी या रूट मॉड्यूल में use_repo_rule इंस्टैंशिएशन शामिल हैं.
  • अगर कॉन्टेक्स्ट रिपॉज़िटरी को WORKSPACE में तय किया गया है, तो:
    1. सबसे पहले, देखें कि कॉन्टेक्स्ट रिपॉज़िटरी की परिभाषा में, मैजिकल repo_mapping एट्रिब्यूट है या नहीं. अगर ऐसा है, तो पहले मैपिंग देखें. इसलिए, repo_mapping = {"@bar": "@baz"} से तय किए गए किसी रिपॉज़िटरी के लिए, हम नीचे @baz देखेंगे.
    2. अगर bar, रूट मॉड्यूल की MODULE.bazel फ़ाइल से शुरू किया गया कोई ऐसा रिपॉज़िटरी नाम है जो साफ़ तौर पर दिखता है, तो @bar उसी पर सेट हो जाता है जिस पर MODULE.bazel फ़ाइल का दावा है. (यह मुख्य रिपॉज़िटरी केस में मौजूद आइटम 1 जैसा ही है.)
    3. इसके अलावा, @bar को @@bar पर सेट किया जा सकता है. ज़्यादातर मामलों में, यह WORKSPACE में तय किए गए किसी रीपो bar पर ले जाएगा. अगर ऐसा कोई रीपो तय नहीं किया गया है, तो Bazel गड़बड़ी का मैसेज दिखाएगा.

कम शब्दों में जानकारी पाने के लिए:

  • Bzlmod-world के रिपॉज़िटरी (मुख्य रिपॉज़िटरी को छोड़कर) को सिर्फ़ Bzlmod-world के रिपॉज़िटरी दिखेंगे.
  • WORKSPACE-world के रिपॉज़िटरी (इसमें मुख्य रिपॉज़िटरी भी शामिल है) में सबसे पहले यह देखा जाएगा कि Bzlmod world में रूट मॉड्यूल क्या तय करता है. इसके बाद, वे WORKSPACE-world के रिपॉज़िटरी देखेंगे.

ध्यान दें कि Bazel कमांड-लाइन में मौजूद लेबल (इनमें Starlark फ़्लैग, लेबल-टाइप वाली फ़्लैग वैल्यू, और बिल्ड/टेस्ट टारगेट पैटर्न शामिल हैं) को मुख्य रिपॉज़िटरी के तौर पर कॉन्टेक्स्ट रिपॉज़िटरी माना जाता है.

अन्य

मैं ऑफ़लाइन बिल्ड को कैसे तैयार और चलाऊं?

रिपॉज़िटरी को पहले से लोड करने के लिए, bazel fetch कमांड का इस्तेमाल करें. सिर्फ़ @foo रिपॉज़िटरी (मुख्य रिपॉज़िटरी के संदर्भ में हल की गई, ऊपर दिया गया सवाल देखें) को फ़ेच करने के लिए, --repo फ़्लैग (bazel fetch --repo @foo की तरह) का इस्तेमाल किया जा सकता है. इसके अलावा, @foo//:bar की सभी ट्रांज़िशन डिपेंडेंसी (यह bazel build --nobuild @foo//:bar के बराबर है) को फ़ेच करने के लिए, टारगेट पैटर्न (bazel fetch @foo//:bar की तरह) का इस्तेमाल किया जा सकता है.

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

अगर आपको लोकल तौर पर टेस्ट करने के लिए, रिपॉज़िटरी फ़ेच करने और उनमें बदलाव करने हैं, तो bazel vendor कमांड का इस्तेमाल करें.

मैं एचटीटीपी प्रॉक्सी का इस्तेमाल कैसे करूं?

Bazel, http_proxy और HTTPS_PROXY एनवायरमेंट वैरिएबल का इस्तेमाल करता है. आम तौर पर, इनका इस्तेमाल curl जैसे अन्य प्रोग्राम करते हैं.

मैं Bazel को ड्यूअल-स्टैक IPv4/IPv6 सेटअप में IPv6 को प्राथमिकता देने के लिए कैसे कहूं?

सिर्फ़ IPv6 वाली मशीनों पर, Bazel बिना किसी बदलाव के डिपेंडेंसी डाउनलोड कर सकता है. हालांकि, ड्यूअल-स्टैक IPv4/IPv6 मशीनों पर, Bazel उसी तरह के समझौते का पालन करता है जिस तरह Java करता है. अगर IPv4 चालू है, तो Bazel उसे प्राथमिकता देता है. कुछ मामलों में, जैसे कि जब IPv4 नेटवर्क, बाहरी पतों को हल नहीं कर पाता/उन तक नहीं पहुंच पाता, तो इससे Network unreachable अपवाद और बिल्ड में गड़बड़ियां हो सकती हैं. ऐसे मामलों में, java.net.preferIPv6Addresses=true सिस्टम प्रॉपर्टी का इस्तेमाल करके, IPv6 को प्राथमिकता देने के लिए, Bazel के व्यवहार को बदला जा सकता है. खास तौर पर:

क्या रिमोट से चलाए जाने की सुविधा की मदद से, रिपॉज़िटरी के नियमों को कहीं से भी चलाया जा सकता है?

नहीं; या कम से कम, अभी नहीं. रिमोट से प्रोग्राम चलाने की सेवाओं का इस्तेमाल करके, अपने बिल्ड को तेज़ करने वाले उपयोगकर्ताओं को यह दिख सकता है कि अब भी रिपॉज़िटरी के नियम स्थानीय तौर पर लागू होते हैं. उदाहरण के लिए, http_archive को पहले लोकल मशीन पर डाउनलोड किया जाएगा (अगर लागू हो, तो किसी भी लोकल डाउनलोड कैश मेमोरी का इस्तेमाल करके), फिर उसे निकाला जाएगा. इसके बाद, हर सोर्स फ़ाइल को इनपुट फ़ाइल के तौर पर, रिमोट इक्विज़िक्यूशन सेवा पर अपलोड किया जाएगा. यह पूछना स्वाभाविक है कि रिमोट से प्रोग्राम चलाने की सेवा, उस संग्रह को डाउनलोड और निकालकर, क्यों काम का राउंड ट्रिप बचाती है.

इसकी एक वजह यह है कि repo के नियम (और मॉड्यूल एक्सटेंशन) उन "स्क्रिप्ट" जैसे होते हैं जिन्हें Bazel खुद चलाता है. ज़रूरी नहीं है कि रिमोट एक्सीक्यूटर में Bazel इंस्टॉल हो.

एक और वजह यह है कि Bazel को अक्सर डाउनलोड किए गए और निकाले गए संग्रह में मौजूद BUILD फ़ाइलों की ज़रूरत होती है, ताकि लोडिंग और विश्लेषण किया जा सके. ये काम स्थानीय तौर पर किए जाते हैं.

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

इस विषय पर हुई पिछली चर्चा के बारे में ज़्यादा जानने के लिए, ऐसा तरीका जिससे उन रिपॉज़िटरी के साथ काम किया जा सके जिन्हें फ़ेच करने के लिए Bazel की ज़रूरत होती है देखें.