Bzlmod माइग्रेशन गाइड

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

वर्कस्पेस की कमियों की वजह से, Bzlmod, Bazel की आने वाली रिलीज़ में लेगसी Workspace सिस्टम की जगह लेगा. इस गाइड से आपको अपने प्रोजेक्ट को Bzlmod पर माइग्रेट करने और बाहरी डिपेंडेंसी पाने के लिए, Workspace को छोड़ने में मदद मिलती है.

SPACESPACE बनाम Bzlmod

Bazel के SPACE और Bzlmod चैनल में, अलग-अलग सिंटैक्स के साथ मिलती-जुलती सुविधाएं हैं. इस सेक्शन में, खास SPACESPACE की सुविधाओं से Bzlmod पर माइग्रेट करने का तरीका बताया गया है.

बैजल वर्कस्पेस का रूट तय करना

यह Workspace फ़ाइल, Bazel प्रोजेक्ट के सोर्स रूट को मार्क करती है. Bazel वर्शन 6.3 और इसके बाद के वर्शन में, इस ज़िम्मेदारी को MODULE.bazel से बदल दिया जाएगा. Bazel के 6.3 से पहले के वर्शन में, आपके फ़ाइल फ़ोल्डर रूट में अब भी WORKSPACE या WORKSPACE.bazel फ़ाइल होनी चाहिए. हो सकता है कि इस तरह की टिप्पणियां हों:

  • वर्कस्पेस

    # This file marks the root of the Bazel workspace.
    # See MODULE.bazel for external dependencies setup.
    

अपने bazelrc में Bzlmod चालू करें

.bazelrc से आपको ऐसे फ़्लैग सेट करने की सुविधा मिलती है जो Bazel चलाने पर, हर बार लागू होते हैं. Bzlmod को चालू करने के लिए, --enable_bzlmod फ़्लैग का इस्तेमाल करें और उसे common कमांड पर लागू करें, ताकि यह हर निर्देश पर लागू हो:

  • .bazelrc

    # Enable Bzlmod for every Bazel command
    common --enable_bzlmod
    

अपने फ़ाइल फ़ोल्डर के लिए डेटा स्टोर करने की जगह का नाम बताएं

  • वर्कस्पेस

    workspace फ़ंक्शन का इस्तेमाल, आपके वर्कस्पेस के लिए रिपॉज़िटरी का नाम बताने के लिए किया जाता है. इससे फ़ाइल फ़ोल्डर में मौजूद टारगेट //foo:bar को @<workspace name>//foo:bar के तौर पर रेफ़र किया जा सकता है. अगर इसकी जानकारी नहीं दी गई है, तो आपके फ़ाइल फ़ोल्डर के लिए डेटा स्टोर करने की डिफ़ॉल्ट जगह का नाम __main__ है.

    ## WORKSPACE
    workspace(name = "com_foo_bar")
    
  • Bzlmod

    हमारा सुझाव है कि आप एक ही फ़ाइल फ़ोल्डर में, @<repo name> के बिना //foo:bar सिंटैक्स के साथ टारगेट का रेफ़रंस दें. हालांकि, अगर आपको पुराने सिंटैक्स की ज़रूरत है, तो डेटा स्टोर करने की जगह के नाम के तौर पर, module फ़ंक्शन से मिले मॉड्यूल के नाम का इस्तेमाल किया जा सकता है. अगर मॉड्यूल का नाम, रिपॉज़िटरी के ज़रूरी नाम से अलग है, तो module फ़ंक्शन के repo_name एट्रिब्यूट का इस्तेमाल करके, डेटा स्टोर करने की जगह का नाम बदला जा सकता है.

    ## MODULE.bazel
    module(
        name = "bar",
        repo_name = "com_foo_bar",
    )
    

बाहरी डिपेंडेंसी को Bazel मॉड्यूल के तौर पर फ़ेच करें

अगर आपकी डिपेंडेंसी एक Bazel प्रोजेक्ट है, तो Bzlmod को अपनाने के बाद, आपको Bazel मॉड्यूल के तौर पर इस पर निर्भर रहना चाहिए.

  • वर्कस्पेस

    Workspace में, आम तौर पर http_archive या git_repository डेटा स्टोर करने की जगह के नियमों का इस्तेमाल करके, Bazel प्रोजेक्ट के सोर्स डाउनलोड किए जाते हैं.

    ## WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
    
    http_archive(
        name = "bazel_skylib",
        urls = ["https://github.com/bazelbuild/bazel-skylib/releases/download/1.4.2/bazel-skylib-1.4.2.tar.gz"],
        sha256 = "66ffd9315665bfaafc96b52278f57c7e2dd09f5ede279ea6d39b2be471e7e3aa",
    )
    load("@bazel_skylib//:workspace.bzl", "bazel_skylib_workspace")
    bazel_skylib_workspace()
    
    http_archive(
        name = "rules_java",
        urls = ["https://github.com/bazelbuild/rules_java/releases/download/6.1.1/rules_java-6.1.1.tar.gz"],
        sha256 = "76402a50ae6859d50bd7aed8c1b8ef09dae5c1035bb3ca7d276f7f3ce659818a",
    )
    load("@rules_java//java:repositories.bzl", "rules_java_dependencies", "rules_java_toolchains")
    rules_java_dependencies()
    rules_java_toolchains()
    

    जैसा कि आप देख सकते हैं, यह एक सामान्य पैटर्न है जिसमें उपयोगकर्ताओं को डिपेंडेंसी के एक मैक्रो से ट्रांज़िटिव डिपेंडेंसी लोड करनी पड़ती है. मान लें कि bazel_skylib और rules_java, platform पर निर्भर करते हैं. platform डिपेंडेंसी का सटीक वर्शन, मैक्रो के क्रम से तय होता है.

  • Bzlmod

    Bzlmod के साथ, अगर Bazel Central Registry या आपकी कस्टम Bazel रजिस्ट्री में आपकी डिपेंडेंसी उपलब्ध है, तो आपको bazel_dep डायरेक्टिव की मदद से इस पर निर्भर रहना होगा.

    ## MODULE.bazel
    bazel_dep(name = "bazel_skylib", version = "1.4.2")
    bazel_dep(name = "rules_java", version = "6.1.1")
    

    Bzlmod, MVS एल्गोरिदम का इस्तेमाल करके, Bazel मॉड्यूल की डिपेंडेंसी को ट्रांसफ़र करता है. इसलिए, platform का ज़्यादा से ज़्यादा ज़रूरी वर्शन अपने-आप चुन लिया जाता है.

Bazel मॉड्यूल के तौर पर डिपेंडेंसी बदलना

रूट मॉड्यूल के तौर पर, Bazel मॉड्यूल की डिपेंडेंसी को अलग-अलग तरीकों से बदला जा सकता है.

ज़्यादा जानकारी के लिए, कृपया overrides सेक्शन पढ़ें.

उदाहरण डेटा स्टोर करने की जगह में, इस्तेमाल के कुछ उदाहरण देखे जा सकते हैं.

मॉड्यूल एक्सटेंशन की मदद से बाहरी डिपेंडेंसी फ़ेच करें

अगर आपका डिपेंडेंसी, Bazel प्रोजेक्ट नहीं है या अब तक किसी भी Bazel रजिस्ट्री में उपलब्ध नहीं है, तो use_repo_rule या मॉड्यूल एक्सटेंशन का इस्तेमाल करके, इसे जोड़ा जा सकता है.

  • वर्कस्पेस

    http_file डेटा स्टोर करने की जगह के नियम का इस्तेमाल करके फ़ाइल डाउनलोड करें.

    ## WORKSPACE
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
    
    http_file(
        name = "data_file",
        url = "http://example.com/file",
        sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    )
    
  • Bzlmod

    Bzlmod के साथ, सीधे रिपॉज़िटरी को इंस्टैंशिएट करने के लिए, अपनी MODULE.bazel फ़ाइल में use_repo_rule डायरेक्टिव का इस्तेमाल करें:

    ## MODULE.bazel
    http_file = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
    http_file(
        name = "data_file",
        url = "http://example.com/file",
        sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
    )
    

    हुड के तहत, इसे मॉड्यूल एक्सटेंशन का इस्तेमाल करके लागू किया जाता है. अगर आपको सिर्फ़ रेपो नियम लागू करने के बजाय, ज़्यादा जटिल लॉजिक लागू करना है, तो खुद भी एक मॉड्यूल एक्सटेंशन लागू किया जा सकता है. आपको परिभाषा को किसी .bzl फ़ाइल में ले जाना होगा. इससे आपको माइग्रेशन की अवधि के दौरान, वर्कस्पेस और Bzlmod के बीच परिभाषा शेयर करने की सुविधा भी मिलेगी.

    ## repositories.bzl
    load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
    def my_data_dependency():
        http_file(
            name = "data_file",
            url = "http://example.com/file",
            sha256 = "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
        )
    

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

    ## extensions.bzl
    load("//:repositories.bzl", "my_data_dependency")
    def _non_module_dependencies_impl(_ctx):
        my_data_dependency()
    
    non_module_dependencies = module_extension(
        implementation = _non_module_dependencies_impl,
    )
    

    रिपॉज़िटरी को रूट प्रोजेक्ट में दिखाने के लिए, आपको MODULE.bazel फ़ाइल में मॉड्यूल एक्सटेंशन और रिपॉज़िटरी के इस्तेमाल के बारे में बताना होगा.

    ## MODULE.bazel
    non_module_dependencies = use_extension("//:extensions.bzl", "non_module_dependencies")
    use_repo(non_module_dependencies, "data_file")
    

मॉड्यूल एक्सटेंशन के साथ कॉन्फ़्लिक्ट एक्सटर्नल डिपेंडेंसी हल करें

कोई प्रोजेक्ट ऐसा मैक्रो उपलब्ध करा सकता है जो अपने कॉलर के इनपुट के आधार पर बाहरी डेटा स्टोर करने की जगह उपलब्ध कराता है. हालांकि, अगर डिपेंडेंसी ग्राफ़ में एक से ज़्यादा कॉलर हों और उनकी वजह से समस्या हो, तो क्या होगा?

मान लें कि प्रोजेक्ट foo नीचे दिया गया मैक्रो देता है, जो version को एक तर्क के तौर पर लेता है.

## repositories.bzl in foo {:#repositories.bzl-foo}
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_file")
def data_deps(version = "1.0"):
    http_file(
        name = "data_file",
        url = "http://example.com/file-%s" % version,
        # Omitting the "sha256" attribute for simplicity
    )
  • वर्कस्पेस

    Workspace की मदद से, @foo से मैक्रो लोड किया जा सकता है. साथ ही, अपनी ज़रूरत के हिसाब से, डेटा डिपेंडेंसी का वर्शन तय किया जा सकता है. मान लें कि आपके पास एक और डिपेंडेंसी @bar है, जो @foo पर भी निर्भर करती है. हालांकि, इसके लिए डेटा डिपेंडेंसी के अलग वर्शन की ज़रूरत होती है.

    ## WORKSPACE
    
    # Introduce @foo and @bar.
    ...
    
    load("@foo//:repositories.bzl", "data_deps")
    data_deps(version = "2.0")
    
    load("@bar//:repositories.bzl", "bar_deps")
    bar_deps() # -> which calls data_deps(version = "3.0")
    

    इस मामले में, असली उपयोगकर्ता को अपनी ज़रूरत का वर्शन पाने के लिए, Workspace में मैक्रो के क्रम में सावधानी से बदलाव करना होगा. यह वर्कस्पेस की सबसे बड़ी समस्याओं में से एक है, क्योंकि यह दूसरे डिपेंडेंसी को ठीक करने का सही तरीका नहीं देता.

  • Bzlmod

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

    ## extensions.bzl in foo
    load("//:repositories.bzl", "data_deps")
    
    data = tag_class(attrs={"version": attr.string()})
    
    def _data_deps_extension_impl(module_ctx):
        # Select the maximal required version in the dependency graph.
        version = "1.0"
        for mod in module_ctx.modules:
            for data in mod.tags.data:
                version = max(version, data.version)
        data_deps(version)
    
    data_deps_extension = module_extension(
        implementation = _data_deps_extension_impl,
        tag_classes = {"data": data},
    )
    
    ## MODULE.bazel in bar
    bazel_dep(name = "foo", version = "1.0")
    
    foo_data_deps = use_extension("@foo//:extensions.bzl", "data_deps_extension")
    foo_data_deps.data(version = "3.0")
    use_repo(foo_data_deps, "data_file")
    
    ## MODULE.bazel in root module
    bazel_dep(name = "foo", version = "1.0")
    bazel_dep(name = "bar", version = "1.0")
    
    foo_data_deps = use_extension("@foo//:extensions.bzl", "data_deps_extension")
    foo_data_deps.data(version = "2.0")
    use_repo(foo_data_deps, "data_file")
    

    इस मामले में, रूट मॉड्यूल को डेटा वर्शन 2.0 की ज़रूरत होती है, जबकि इसकी डिपेंडेंसी bar को 3.0 की ज़रूरत होती है. foo में मौजूद मॉड्यूल एक्सटेंशन, इस विरोधाभास को सही तरीके से हल कर सकता है और डेटा डिपेंडेंसी के लिए अपने-आप 3.0 वर्शन चुन सकता है.

तीसरे पक्ष के पैकेज मैनेजर को इंटिग्रेट करें

आखिरी सेक्शन के बाद, मॉड्यूल एक्सटेंशन डिपेंडेंसी ग्राफ़ से जानकारी इकट्ठा करने, डिपेंडेंसी को रिज़ॉल्व करने के लिए कस्टम लॉजिक इस्तेमाल करने, और डेटा स्टोर करने की जगह के नियमों को कॉल करने का तरीका देता है. इससे, नियमों के लेखकों को खास भाषाओं के लिए पैकेज मैनेजर को इंटिग्रेट करने वाले नियमों को बेहतर बनाने का शानदार तरीका मिलता है.

मॉड्यूल एक्सटेंशन को इस्तेमाल करने के तरीके के बारे में ज़्यादा जानने के लिए, कृपया मॉड्यूल एक्सटेंशन पेज पढ़ें.

यहां उन नियमों की सूची दी गई है जो पहले से ही Bzlmod का इस्तेमाल कर रहे हैं, ताकि अलग-अलग पैकेज मैनेजर की मदद से डिपेंडेंसी फ़ेच की जा सके:

सूडो पैकेज मैनेजर को इंटिग्रेट करने वाला एक छोटा सा उदाहरण, examples डेटा स्टोर करने की जगह पर उपलब्ध है.

होस्ट मशीन पर टूलचेन का पता लगाएं

जब Bazel के बिल्ड नियमों को यह पता लगाना पड़ता है कि आपकी होस्ट मशीन पर कौनसे टूलचेन उपलब्ध हैं, तब वे होस्ट मशीन की जांच करने के लिए, डेटा स्टोर करने की जगह के नियमों का इस्तेमाल करते हैं. साथ ही, टूलचेन की जानकारी को बाहरी डेटा स्टोर करने की जगह के तौर पर जनरेट करते हैं.

  • वर्कस्पेस

    शेल टूलचेन का पता लगाने के लिए, डेटा स्टोर करने के इस नियम का पालन किया गया है.

    ## local_config_sh.bzl
    def _sh_config_rule_impl(repository_ctx):
        sh_path = get_sh_path_from_env("SH_BIN_PATH")
    
        if not sh_path:
            sh_path = detect_sh_from_path()
    
        if not sh_path:
            sh_path = "/shell/binary/not/found"
    
        repository_ctx.file("BUILD", """
    load("@bazel_tools//tools/sh:sh_toolchain.bzl", "sh_toolchain")
    sh_toolchain(
        name = "local_sh",
        path = "{sh_path}",
        visibility = ["//visibility:public"],
    )
    toolchain(
        name = "local_sh_toolchain",
        toolchain = ":local_sh",
        toolchain_type = "@bazel_tools//tools/sh:toolchain_type",
    )
    """.format(sh_path = sh_path))
    
    sh_config_rule = repository_rule(
        environ = ["SH_BIN_PATH"],
        local = True,
        implementation = _sh_config_rule_impl,
    )
    

    आपके पास वर्कस्पेस में डेटा स्टोर करने की जगह के नियम को लोड करने का विकल्प है.

    ## WORKSPACE
    load("//:local_config_sh.bzl", "sh_config_rule")
    sh_config_rule(name = "local_config_sh")
    
  • Bzlmod

    Bzlmod के साथ, मॉड्यूल एक्सटेंशन का इस्तेमाल करके उसी रिपॉज़िटरी को पेश किया जा सकता है. यह पिछले सेक्शन में, @data_file रिपॉज़िटरी के बारे में बताने जैसा ही है.

    ## local_config_sh_extension.bzl
    load("//:local_config_sh.bzl", "sh_config_rule")
    
    sh_config_extension = module_extension(
        implementation = lambda ctx: sh_config_rule(name = "local_config_sh"),
    )
    

    इसके बाद, MODULE.bazel फ़ाइल में एक्सटेंशन का इस्तेमाल करें.

    ## MODULE.bazel
    sh_config_ext = use_extension("//:local_config_sh_extension.bzl", "sh_config_extension")
    use_repo(sh_config_ext, "local_config_sh")
    

टूलचेन और एक्ज़ीक्यूशन प्लैटफ़ॉर्म को रजिस्टर करें

आखिरी सेक्शन के बाद, रिपॉज़िटरी होस्टिंग टूलचेन से जुड़ी जानकारी (जैसे, local_config_sh) उपलब्ध कराने के बाद, हो सकता है कि आप टूलचेन को रजिस्टर करना चाहें.

  • वर्कस्पेस

    Workspace से, टूलचेन को इन तरीकों से रजिस्टर किया जा सकता है.

    1. आपके पास टूलचेन को .bzl फ़ाइल में रजिस्टर करने और मैक्रो को Workspace फ़ाइल में लोड करने का विकल्प है.

      ## local_config_sh.bzl
      def sh_configure():
          sh_config_rule(name = "local_config_sh")
          native.register_toolchains("@local_config_sh//:local_sh_toolchain")
      
      ## WORKSPACE
      load("//:local_config_sh.bzl", "sh_configure")
      sh_configure()
      
    2. इसके अलावा, टूलचेन को सीधे वर्कSPACE फ़ाइल में रजिस्टर करें.

      ## WORKSPACE
      load("//:local_config_sh.bzl", "sh_config_rule")
      sh_config_rule(name = "local_config_sh")
      register_toolchains("@local_config_sh//:local_sh_toolchain")
      
  • Bzlmod

    Bzlmod पर, register_toolchains और register_execution_platforms एपीआई सिर्फ़ MODULE.bazel फ़ाइल में उपलब्ध हैं. मॉड्यूल एक्सटेंशन में native.register_toolchains को कॉल नहीं किया जा सकता.

    ## MODULE.bazel
    sh_config_ext = use_extension("//:local_config_sh_extension.bzl", "sh_config_extension")
    use_repo(sh_config_ext, "local_config_sh")
    register_toolchains("@local_config_sh//:local_sh_toolchain")
    

WORKSPACE, WORKSPACE.bzlmod में रजिस्टर किए गए टूलचेन और एक्ज़ीक्यूशन प्लैटफ़ॉर्म और हर Bazel मॉड्यूल की MODULE.bazel फ़ाइल, टूलचेन चुनने के दौरान प्राथमिकता के इस क्रम का पालन करती है (सबसे ज़्यादा से सबसे कम):

  1. रूट मॉड्यूल की MODULE.bazel फ़ाइल में रजिस्टर किए गए टूलचेन और एक्ज़ीक्यूशन प्लैटफ़ॉर्म.
  2. WORKSPACE या WORKSPACE.bzlmod फ़ाइल में रजिस्टर किए गए टूलचेन और एक्ज़ीक्यूशन प्लैटफ़ॉर्म.
  3. ऐसे टूलचेन और एक्ज़ीक्यूशन प्लैटफ़ॉर्म जिन्हें मॉड्यूल से रजिस्टर किया जाता है. ये मॉड्यूल, रूट मॉड्यूल की डिपेंडेंसी होते हैं.
  4. WORKSPACE.bzlmod का इस्तेमाल नहीं किए जाने पर: WORKSPACE सफ़िक्स में रजिस्टर की गई टूलचेन.

डेटा स्टोर करने की स्थानीय जगहों के बारे में बताना

अगर आपको डीबग करने के लिए, डिपेंडेंसी के लोकल वर्शन की ज़रूरत है या आपको अपने फ़ाइल फ़ोल्डर में किसी डायरेक्ट्री को बाहरी रिपॉज़िटरी के तौर पर शामिल करना है, तो आपको लोकल रिपॉज़िटरी के तौर पर, डिपेंडेंसी लागू करनी पड़ सकती है.

  • वर्कस्पेस

    Workspace की मदद से, यह लक्ष्य डेटा स्टोर करने की जगह के दो नेटिव नियमों, local_repository और new_local_repository से मिलता है.

    ## WORKSPACE
    local_repository(
        name = "rules_java",
        path = "/Users/bazel_user/workspace/rules_java",
    )
    
  • Bzlmod

    Bzlmod पर, किसी मॉड्यूल को लोकल पाथ से बदलने के लिए, local_path_override का इस्तेमाल किया जा सकता है.

    ## MODULE.bazel
    bazel_dep(name = "rules_java")
    local_path_override(
        module_name = "rules_java",
        path = "/Users/bazel_user/workspace/rules_java",
    )
    

    मॉड्यूल एक्सटेंशन के साथ एक लोकल रिपॉज़िटरी भी उपलब्ध कराई जा सकती है. हालांकि, मॉड्यूल एक्सटेंशन में native.local_repository को कॉल नहीं किया जा सकता. डेटा स्टोर करने के सभी नेटिव नियमों को स्टार के तौर पर तय करने की कोशिश की जा रही है. प्रोग्रेस देखने के लिए, #18285 देखें. इसके बाद, किसी मॉड्यूल एक्सटेंशन में उससे जुड़े स्टारलार्क local_repository को कॉल किया जा सकता है. अगर आपको ब्लॉक करने से जुड़ी कोई समस्या है, तो डेटा स्टोर करने की जगह के local_repository नियम के कस्टम वर्शन को लागू करना भी आसान है.

बाइंड टारगेट

Workspace में bind नियम अब काम नहीं करता और Bzlmod में काम नहीं करता. इसकी शुरुआत इसलिए की गई थी, ताकि //external के खास पैकेज में टारगेट को कोई उपनाम दिया जा सके. इस आधार पर, सभी उपयोगकर्ताओं को माइग्रेट करना होगा.

उदाहरण के लिए, अगर आपके पास

## WORKSPACE
bind(
    name = "openssl",
    actual = "@my-ssl//src:openssl-lib",
)

इससे दूसरे टारगेट, //external:openssl पर निर्भर हो सकते हैं. इससे माइग्रेट करने के लिए:

  • //external:openssl के सभी इस्तेमाल को @my-ssl//src:openssl-lib से बदलें.

  • या alias बिल्ड नियम का इस्तेमाल करें

    • किसी पैकेज में यह टारगेट तय करें (उदाहरण के लिए, //third_party)

      ## third_party/BUILD
      alias(
          name = "openssl",
          actual = "@my-ssl//src:openssl-lib",
      )
      
    • //external:openssl के सभी इस्तेमाल को //third_party:openssl से बदलें.

फ़ेच बनाम सिंक

'फ़ेच और सिंक करें' निर्देशों का इस्तेमाल, बाहरी डेटा संग्रह को स्थानीय तौर पर डाउनलोड करने और उन्हें अपडेट रखने के लिए किया जाता है. कभी-कभी बिल्ड के लिए ज़रूरी सभी डेटा को फ़ेच करने के बाद, --nofetch फ़्लैग का इस्तेमाल करके ऑफ़लाइन बिल्डिंग बनाने की अनुमति भी दी जाती है.

  • वर्कस्पेस

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

  • Bzlmod

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

माइग्रेशन

यह सेक्शन Bzlmod माइग्रेशन की प्रोसेस के लिए, काम की जानकारी और दिशा-निर्देश देता है.

Workspace में अपनी डिपेंडेंसी के बारे में जानें

माइग्रेशन का सबसे पहला चरण यह समझना है कि आपके पास कौन-कौनसी निर्भरियां हैं. यह पता करना मुश्किल हो सकता है कि Workspace फ़ाइल में किस तरह की डिपेंडेंसी लागू की गई हैं. इसकी वजह यह है कि ट्रांज़िटिव डिपेंडेंसी अक्सर *_deps मैक्रो के साथ लोड की जाती हैं.

फ़ाइल फ़ोल्डर की समाधान की गई फ़ाइल के साथ बाहरी डिपेंडेंसी की जांच करें

अच्छी बात यह है कि फ़्लैग --experimental_repository_resolved_file से मदद मिल सकती है. यह फ़्लैग, आपके आखिरी Bazel निर्देश में, फ़ेच की गई सभी बाहरी डिपेंडेंसी की "लॉक फ़ाइल" जनरेट करता है. आपको इस ब्लॉग पोस्ट में ज़्यादा जानकारी मिल सकती है.

इसका इस्तेमाल दो तरीकों से किया जा सकता है:

  1. कुछ टारगेट बनाने के लिए ज़रूरी बाहरी डिपेंडेंसी की जानकारी पाने के लिए.

    bazel clean --expunge
    bazel build --nobuild --experimental_repository_resolved_file=resolved.bzl //foo:bar
    
  2. वर्कस्पेस फ़ाइल में दी गई सभी बाहरी डिपेंडेंसी की जानकारी फ़ेच करने के लिए.

    bazel clean --expunge
    bazel sync --experimental_repository_resolved_file=resolved.bzl
    

    bazel sync कमांड का इस्तेमाल करके, Workspace फ़ाइल में बताई गई सभी डिपेंडेंसी फ़ेच की जा सकती हैं. इनमें ये शामिल हैं:

    • bind बार इस्तेमाल किया गया
    • register_toolchains और register_execution_platforms बार इस्तेमाल किया गया

    हालांकि, अगर आपका प्रोजेक्ट क्रॉस प्लैटफ़ॉर्म है, तो कुछ प्लैटफ़ॉर्म पर बैजल सिंक काम करना बंद कर सकता है. ऐसा इसलिए होता है, क्योंकि डेटा स्टोर करने की कुछ जगहों के नियम, सिर्फ़ उन प्लैटफ़ॉर्म पर ठीक से चल सकते हैं जिन पर यह सुविधा काम करती है.

कमांड चलाने के बाद, resolved.bzl फ़ाइल में आपके पास अपनी बाहरी डिपेंडेंसी की जानकारी होनी चाहिए.

bazel query के साथ बाहरी डिपेंडेंसी की जांच करें

आपको यह भी पता होगा कि bazel query का इस्तेमाल, डेटा स्टोर करने की जगह के नियमों की जांच करने के लिए किया जा सकता है. इसके लिए,

bazel query --output=build //external:<repo name>

यह ज़्यादा आसान और तेज़ है, लेकिन bazel क्वेरी बाहरी डिपेंडेंसी वर्शन के बारे में हो सकती है. इसलिए, इसका इस्तेमाल करते समय सावधानी बरतें! Bzlmod की मदद से, बाहरी डिपेंडेंसी के बारे में क्वेरी करने और उसकी जांच करने का काम एक नया सब-कमांड पूरा करेगा.

पहले से मौजूद डिफ़ॉल्ट डिपेंडेंसी

अगर --experimental_repository_resolved_file से जनरेट की गई फ़ाइल देखी जाती है, तो आपको ऐसी कई डिपेंडेंसी मिलेंगी जिनके बारे में आपके Workspace में नहीं बताया गया है. ऐसा इसलिए है, क्योंकि Bazel कुछ डिफ़ॉल्ट डिपेंडेंसी इंजेक्ट करने के लिए, उपयोगकर्ता की Workspace फ़ाइल के कॉन्टेंट में प्रीफ़िक्स और सफ़िक्स जोड़ता है. आम तौर पर, इन नियमों की ज़रूरत नेटिव नियमों (जैसे, @bazel_tools, @platforms, और @remote_java_tools) के लिए होती है. Bzlmod के साथ, ये डिपेंडेंसी बिल्ट-इन मॉड्यूल के साथ मिलती हैं, जो हर दूसरे Bazel मॉड्यूल के लिए डिफ़ॉल्ट डिपेंडेंसी है.bazel_tools

धीरे-धीरे माइग्रेशन के लिए हाइब्रिड मोड

Bzlmod और workspace, साथ-साथ काम कर सकता है. इससे, वर्कस्पेस फ़ाइल से Bzlmod पर डिपेंडेंसी को माइग्रेट करने की प्रोसेस धीरे-धीरे होती है.

WORKSPACE.bzlmod

माइग्रेशन के दौरान, Bazel उपयोगकर्ताओं को Bzlmod चालू किए गए और उसके बिना, बिल्ड के बीच स्विच करना पड़ सकता है. प्रक्रिया को आसान बनाने के लिए, SPACESPACE.bzlmod सहायता का इस्तेमाल किया जाता है.

workSPACE.bzlmod का सिंटैक्स बिलकुल WorkSPACE जैसा है. Bzlmod चालू होने पर, अगर फ़ाइल फ़ोल्डर के रूट में भी WorkspaceSPACE.bzlmod फ़ाइल मौजूद है, तो:

  • WORKSPACE.bzlmod लागू होता है और WORKSPACE के कॉन्टेंट को अनदेखा कर दिया जाता है.
  • WorkspaceSPACE.bzlmod फ़ाइल में कोई प्रीफ़िक्स या सफ़िक्स नहीं जोड़ा जाता.

WorkspaceSPACE.bzlmod फ़ाइल का इस्तेमाल करने से माइग्रेशन आसानी से हो सकता है, क्योंकि:

  • Bzlmod बंद होने पर, ओरिजनल वर्कSPACE फ़ाइल से डिपेंडेंसी फ़ेच की जा सकती है.
  • Bzlmod चालू होने पर, WorkSPACE.bzlmod के साथ माइग्रेट करने के लिए बची हुई डिपेंडेंसी को बेहतर तरीके से ट्रैक कर सकते हैं.

डेटा स्टोर करने की जगह की विज़िबिलिटी

Bzlmod यह कंट्रोल कर सकता है कि किसी डेटा स्टोर करने की जगह से कौनसे दूसरे डेटा स्टोर किए जाएंगे. ज़्यादा जानकारी के लिए, डेटा स्टोर करने की जगह के नाम और सख्त डेटा स्टोर करने की जगह देखें.

यहां अलग-अलग तरह के डेटा स्टोर करने की जगहों से, डेटा स्टोर करने की जगहों के बारे में खास जानकारी दी गई है. हालांकि, ऐसा तब भी किया जा रहा है, जब WorkspaceSPACE पर ध्यान दिया जा रहा हो.

मुख्य डेटा स्टोर करने की सुविधा से Bazel मॉड्यूल रिपॉस से मॉड्यूल एक्सटेंशन डेटा स्टोर करने की जगहों से Workspace repos से
डेटा स्टोर करने की मुख्य जगह दिख रहा है अगर रूट मॉड्यूल डायरेक्ट डिपेंडेंसी है अगर रूट मॉड्यूल, मॉड्यूल एक्सटेंशन को होस्ट करने वाले मॉड्यूल पर सीधे तौर पर निर्भर है दिख रहा है
Bazel मॉड्यूल रिपॉस डायरेक्ट डिपेंस डायरेक्ट डिपेंस मॉड्यूल एक्सटेंशन को होस्ट करने वाले मॉड्यूल का डायरेक्ट डिप रूट मॉड्यूल के डायरेक्ट डिप्स
मॉड्यूल एक्सटेंशन डेटा स्टोर करने की सुविधा डायरेक्ट डिपेंस डायरेक्ट डिपेंस मॉड्यूल एक्सटेंशन को होस्ट करने वाले मॉड्यूल के डायरेक्ट डिप और एक ही मॉड्यूल एक्सटेंशन से जनरेट किए गए सभी डेटा स्टोर रूट मॉड्यूल के डायरेक्ट डिप्स
Workspace के डेटा स्टोर करने की जगह सभी दृश्यमान नहीं दिख रहा है नहीं दिख रहा है सभी दृश्यमान
@bar

माइग्रेट करने का तरीका

Bzlmod माइग्रेशन की सामान्य प्रोसेस कुछ इस तरह दिख सकती है:

  1. जानें कि Workspace में आपकी कौनसी डिपेंडेंसी है.
  2. अपने प्रोजेक्ट रूट में एक खाली MODULE.bazel फ़ाइल जोड़ें.
  3. वर्कस्पेस फ़ाइल के कॉन्टेंट को बदलने के लिए, एक खाली Workspace.bzlmod फ़ाइल जोड़ें.
  4. Bzlmod चालू करके, अपने टारगेट बनाएं और देखें कि कौनसा डेटा स्टोर करने की जगह मौजूद नहीं है.
  5. डिपेंडेंसी फ़ाइल में रिपॉज़िटरी की वह परिभाषा देखें जो मौजूद नहीं है.
  6. किसी मॉड्यूल एक्सटेंशन की मदद से, Bazel मॉड्यूल के तौर पर, छूटी हुई डिपेंडेंसी का परिचय दें या उसे बाद में माइग्रेट करने के लिए, WorkSPACE.bzlmod में छोड़ें.
  7. 4 पर वापस जाएं और सभी डिपेंडेंसी उपलब्ध होने तक इस प्रक्रिया को दोहराएं.

डेटा दूसरी जगह भेजने के लिए टूल

एक इंटरैक्टिव Bzlmod माइग्रेशन हेल्पर स्क्रिप्ट मौजूद है, जिससे आप शुरुआत कर सकते हैं.

स्क्रिप्ट ये काम करती है:

  • SPACESPACE की समाधान की गई फ़ाइल को जनरेट और पार्स करें.
  • समाधान की गई फ़ाइल में मौजूद डेटा स्टोर करने की जगह की जानकारी को मैन्युअल तरीके से प्रिंट करें.
  • bazel बिल्ड कमांड चलाएं, पहचाने गए गड़बड़ी के मैसेज का पता लगाएं, और माइग्रेट करने का कोई तरीका सुझाएं.
  • देखें कि बीसीआर में कोई डिपेंडेंसी पहले से उपलब्ध है या नहीं.
  • MODULE.bazel फ़ाइल पर कोई डिपेंडेंसी जोड़ें.
  • मॉड्यूल एक्सटेंशन की मदद से डिपेंडेंसी जोड़ें.
  • SPACESPACE.bzlmod फ़ाइल में कोई डिपेंडेंसी जोड़ें.

इसका इस्तेमाल करने के लिए, पक्का करें कि आपके पास Bazel का नया वर्शन इंस्टॉल है. साथ ही, इस निर्देश का इस्तेमाल करें:

git clone https://github.com/bazelbuild/bazel-central-registry.git
cd <your workspace root>
<BCR repo root>/tools/migrate_to_bzlmod.py -t <your build targets>

Bazel मॉड्यूल पब्लिश करें

अगर आपका Bazel प्रोजेक्ट, दूसरे प्रोजेक्ट पर निर्भर है, तो आप Bazel Central Registry में अपना प्रोजेक्ट पब्लिश कर सकते हैं.

बीसीआर में अपने प्रोजेक्ट की जांच करने के लिए, आपको प्रोजेक्ट के सोर्स संग्रह यूआरएल की ज़रूरत होगी. सोर्स संग्रह बनाते समय कुछ चीज़ों का ध्यान रखें:

  • पक्का करें कि संग्रह किसी खास वर्शन से जुड़ा हो.

    BCR सिर्फ़ वर्शन वाले सोर्स संग्रहों को स्वीकार कर सकता है, क्योंकि Bzlmod को डिपेंडेंसी रिज़ॉल्यूशन के दौरान वर्शन की तुलना करनी होती है.

  • पक्का करें कि संग्रह का यूआरएल स्टेबल हो.

    Bazel, हैश वैल्यू के ज़रिए संग्रह के कॉन्टेंट की पुष्टि करता है. इसलिए, आपको यह पक्का करना चाहिए कि डाउनलोड की गई फ़ाइल का चेकसम कभी न बदले. अगर यूआरएल GitHub का है, तो कृपया रिलीज़ पेज पर रिलीज़ संग्रह बनाएं और उसे अपलोड करें. GitHub, मांग पर जनरेट किए गए सोर्स संग्रह की जांच की गारंटी नहीं देगा. संक्षेप में, https://github.com/<org>/<repo>/releases/download/... वाले यूआरएल को स्थिर माना जाता है, जबकि https://github.com/<org>/<repo>/archive/... नहीं. ज़्यादा जानकारी के लिए, GitHub संग्रह की जांच आउटेज देखें.

  • पक्का करें कि सोर्स ट्री, डेटा स्टोर करने की मूल जगह के लेआउट के हिसाब से हो.

    अगर आपका डेटा स्टोर करने की जगह बहुत बड़ी है और आपको गै़र-ज़रूरी सोर्स हटाकर, कम साइज़ वाला डिस्ट्रिब्यूशन कलेक्शन बनाना है, तो कृपया पक्का करें कि हटाया गया सोर्स ट्री, ओरिजनल सोर्स ट्री का सबसेट है. इससे असली उपयोगकर्ता, archive_override और git_override तक मॉड्यूल को, रिलीज़ नहीं किए गए वर्शन में बदल सकते हैं.

  • किसी सबडायरेक्ट्री में टेस्ट मॉड्यूल शामिल करें, जो आपके सबसे आम एपीआई की जांच करता हो.

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

जब आपके सोर्स संग्रह का यूआरएल तैयार हो जाए, तो BCR में योगदान देने के दिशा-निर्देशों का पालन करें. इससे आपका मॉड्यूल GitHub पर पुल किए गए अनुरोध के साथ, BCR में सबमिट किया जा सकेगा.

हमारा सुझाव है कि आप अपने डेटा स्टोर करने की जगह के लिए, BCR पर पब्लिश करें GitHub ऐप्लिकेशन को सेट अप करें. इससे, BCR में आपका मॉड्यूल सबमिट करने की प्रोसेस अपने-आप पूरी हो जाएगी.

सबसे सही तरीके

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

ग़ैर-ज़रूरी डिपेंडेंसी फ़ेच करने के लिए, टारगेट को अलग-अलग पैकेज में बांटें.

#12835 देखें, जहां टेस्ट के लिए डेवलपर की डिपेंडेंसी को बिना अनुमति के फ़ेच किया जाता है. ऐसा उन टारगेट को बनाने के लिए किया जाता है जिन्हें इनकी ज़रूरत नहीं होती. यह Bzlmod के लिए नहीं है. हालांकि, यह तरीका अपनाने से डेवलपर डिपेंडेंसी को सही तरीके से तय करना आसान हो जाता है.

डेव डिपेंडेंसी के बारे में बताएं

bazel_dep और use_extension डायरेक्टिव के लिए, dev_dependency एट्रिब्यूट को 'सही' पर सेट किया जा सकता है, ताकि वे डिपेंडेंट प्रोजेक्ट पर लागू न हों. रूट मॉड्यूल के तौर पर, --ignore_dev_dependency फ़्लैग का इस्तेमाल करके यह पुष्टि की जा सकती है कि आपके टारगेट अब भी डेवलपर के डिपेंडेंसी के बिना बनाए जा रहे हैं या नहीं.

समुदाय के डेटा को दूसरी जगह भेजने की प्रक्रिया

Bazel Central Registry पर जाकर, यह पता किया जा सकता है कि आपकी डिपेंडेंसी पहले से उपलब्ध हैं या नहीं. अगर ऐसा नहीं है, तो आपके माइग्रेशन को रोकने वाली डिपेंडेंसी के पक्ष में वोट करने या उसे पोस्ट करने के लिए, इस GitHub चर्चा में शामिल हों.

समस्याओं की शिकायत करना

Bzlmod से जुड़ी जानी-पहचानी समस्याओं के लिए, कृपया Bazel GitHub से जुड़ी समस्या की सूची देखें. नई समस्याओं को दर्ज करें या सुविधा के अनुरोध करें. इनसे, माइग्रेशन को अनब्लॉक करने में मदद मिलेगी!