WORKSPACE की कमियों की वजह से, Bzlmod, लेगसी WORKSPACE सिस्टम की जगह ले रहा है. Bazel 8 (साल 2024 के आखिर में) में WORKSPACE फ़ाइल पहले से ही बंद है. इसे Bazel 9 (साल 2025 के आखिर में) में हटा दिया जाएगा. इस गाइड की मदद से, अपने प्रोजेक्ट को Bzlmod पर माइग्रेट किया जा सकता है. साथ ही, बाहरी डिपेंडेंसी मैनेज करने के लिए WORKSPACE को हटाया जा सकता है.
Bzlmod पर क्यों माइग्रेट करना चाहिए?
लेगसी WORKSPACE सिस्टम की तुलना में, इसमें कई फ़ायदे हैं. इससे Bazel के नेटवर्क को बेहतर तरीके से बढ़ाने में मदद मिलती है.
अगर आपका प्रोजेक्ट, अन्य प्रोजेक्ट पर निर्भर है, तो Bzlmod पर माइग्रेट करने से, उन प्रोजेक्ट के माइग्रेशन में आने वाली रुकावट दूर हो जाएगी. साथ ही, वे आसानी से आपके प्रोजेक्ट पर निर्भर हो पाएंगे.
Bazel के आने वाले वर्शन का इस्तेमाल करने के लिए, Bzlmod पर माइग्रेट करना ज़रूरी है. Bazel 9 में यह ज़रूरी है.
Bzlmod पर माइग्रेट करने का तरीका क्या है?
माइग्रेट करने का सुझाया गया तरीका:
- माइग्रेशन की प्रोसेस को आसान बनाने के लिए, माइग्रेशन टूल का इस्तेमाल करें. माइग्रेशन टूल और टूल इस्तेमाल करने का तरीका सेक्शन देखें.
- अगर माइग्रेशन टूल का इस्तेमाल करने के बाद भी गड़बड़ियां बनी रहती हैं, तो उन्हें मैन्युअल तरीके से ठीक करें.
WORKSPACE
औरMODULE.bazel
फ़ाइलों में मौजूद कॉन्सेप्ट के बीच मुख्य अंतर समझने के लिए, WORKSPACE बनाम Bzlmod सेक्शन देखें.
माइग्रेशन टूल
WORKSPACE से Bzlmod पर माइग्रेट करने की प्रोसेस अक्सर जटिल होती है. इसलिए, हमारा सुझाव है कि आप माइग्रेशन स्क्रिप्ट का इस्तेमाल करें. यह हेल्पर टूल, बाहरी डिपेंडेंसी मैनेजमेंट सिस्टम को माइग्रेट करने से जुड़े कई चरणों को अपने-आप पूरा करता है.
मुख्य फ़ंक्शन
स्क्रिप्ट के मुख्य काम ये हैं:
- डिपेंडेंसी की जानकारी इकट्ठा करना: यह आपके प्रोजेक्ट की
WORKSPACE
फ़ाइल का विश्लेषण करता है, ताकि यह पता लगाया जा सके कि तय किए गए बिल्ड टारगेट के लिए कौनसी बाहरी रिपॉज़िटरी इस्तेमाल की गई हैं. यह इस जानकारी वालीresolved_deps.py
फ़ाइल को जनरेट करने के लिए, Bazel के experimental_repository_resolved_file फ़्लैग का इस्तेमाल करता है. - सीधे तौर पर निर्भरता की पहचान करना: यह
bazel query
का इस्तेमाल करके यह पता लगाता है कि बताए गए टारगेट के लिए, कौनसी रिपॉज़िटरी सीधे तौर पर निर्भर हैं. - Bzlmod माइग्रेशन: यह
WORKSPACE
डिपेंडेंसी को उनके Bzlmod वर्शन में बदलता है. यह दो चरणों वाली प्रोसेस है:- यह फ़ाइल में पहचानी गई सभी डायरेक्ट डिपेंडेंसी को शामिल करने की कोशिश करता है.
MODULE.bazel
- Bzlmod चालू होने पर, तय किए गए टारगेट बनाने की कोशिश करता है. इसके बाद, पहचान की जा सकने वाली गड़बड़ियों का पता लगाकर उन्हें ठीक करता है. इस चरण की ज़रूरत इसलिए है, क्योंकि हो सकता है कि पहले चरण में कुछ डिपेंडेंसी मौजूद न हों.
- यह फ़ाइल में पहचानी गई सभी डायरेक्ट डिपेंडेंसी को शामिल करने की कोशिश करता है.
- माइग्रेशन रिपोर्ट जनरेट करना: इससे एक
migration_info.md
फ़ाइल बनती है. इसमें माइग्रेशन की प्रोसेस के बारे में जानकारी होती है. इस रिपोर्ट में, डायरेक्ट डिपेंडेंसी की सूची, जनरेट किए गए Bzlmod एलान, और माइग्रेशन पूरा करने के लिए ज़रूरी मैन्युअल चरणों की जानकारी शामिल होती है.
माइग्रेशन टूल इन सुविधाओं के साथ काम करता है:
- Bazel Central Registry में उपलब्ध डिपेंडेंसी
- उपयोगकर्ता की ओर से तय किए गए कस्टम रिपॉज़िटरी नियम
- पैकेज मैनेजर की डिपेंडेंसी
- Maven (rules_jvm_external)
- जाएं (rules_go)
- [आने वाला] Python (rules_python)
अहम जानकारी: माइग्रेशन टूल, सबसे बेहतर तरीके से काम करने वाला टूल है. हमेशा यह पक्का करें कि इसके सुझाव सही हों.
माइग्रेशन टूल का इस्तेमाल कैसे करें
शुरू करने से पहले:
- Bazel 7 के नए वर्शन पर अपग्रेड करें. यह WORKSPACE और Bzlmod, दोनों के लिए बेहतर तरीके से काम करता है.
पुष्टि करें कि आपके प्रोजेक्ट के मुख्य बिल्ड टारगेट के लिए, यह निर्देश सही तरीके से काम कर रहा है:
bazel build --nobuild --enable_workspace --noenable_bzlmod <targets>
ज़रूरी शर्तें पूरी होने के बाद, माइग्रेशन टूल का इस्तेमाल करने के लिए, यहां दिए गए निर्देश चलाएं:
# Clone the Bazel Central Registry repository
git clone https://github.com/bazelbuild/bazel-central-registry.git
cd bazel-central-registry
# Build the migration tool
bazel build //tools:migrate_to_bzlmod
# Create a convenient alias for the tool
alias migrate2bzlmod=$(realpath ./bazel-bin/tools/migrate_to_bzlmod)
# Navigate to your project's root directory and run the tool
cd <your workspace root>
migrate2bzlmod -t <your build targets>
WORKSPACE बनाम Bzlmod
Bazel के WORKSPACE और Bzlmod में एक जैसी सुविधाएं मिलती हैं, लेकिन इनके सिंटैक्स अलग-अलग होते हैं. इस सेक्शन में, WORKSPACE की कुछ खास सुविधाओं से Bzlmod पर माइग्रेट करने का तरीका बताया गया है.
Bazel वर्कस्पेस का रूट तय करना
WORKSPACE फ़ाइल, Bazel प्रोजेक्ट के सोर्स रूट को मार्क करती है. Bazel 6.3 और इसके बाद के वर्शन में, यह काम MODULE.bazel फ़ाइल करती है. Bazel के 6.3 से पहले के वर्शन में, आपके वर्कस्पेस के रूट में अब भी WORKSPACE
या WORKSPACE.bazel
फ़ाइल होनी चाहिए. हो सकता है कि इसमें इस तरह की टिप्पणियां हों:
WORKSPACE
# 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
workspace
फ़ंक्शन का इस्तेमाल, अपने फ़ाइल फ़ोल्डर के लिए रिपॉज़िटरी का नाम तय करने के लिए किया जाता है. इससे वर्कस्पेस में मौजूद किसी टारगेट//foo:bar
को@<workspace name>//foo:bar
के तौर पर रेफ़रंस किया जा सकता है. अगर इसकी जानकारी नहीं दी जाती है, तो आपके वर्कस्पेस के लिए डिफ़ॉल्ट रिपॉज़िटरी का नाम__main__
होता है.## WORKSPACE workspace(name = "com_foo_bar")
Bzlmod
हमारा सुझाव है कि आप एक ही वर्कस्पेस में मौजूद टारगेट को
//foo:bar
सिंटैक्स के साथ रेफ़रंस करें. इसके लिए,@<repo name>
का इस्तेमाल न करें. हालांकि, अगर आपको पुराने सिंटैक्स की ज़रूरत है, तोmodule
फ़ंक्शन से तय किए गए मॉड्यूल के नाम का इस्तेमाल, रिपॉज़िटरी के नाम के तौर पर किया जा सकता है. अगर मॉड्यूल का नाम, ज़रूरी रिपॉज़िटरी के नाम से अलग है, तो रिपॉज़िटरी के नाम को बदलने के लिए,module
फ़ंक्शन केrepo_name
एट्रिब्यूट का इस्तेमाल किया जा सकता है.## MODULE.bazel module( name = "bar", repo_name = "com_foo_bar", )
Bazel मॉड्यूल के तौर पर बाहरी डिपेंडेंसी फ़ेच करना
अगर आपकी डिपेंडेंसी कोई Bazel प्रोजेक्ट है, तो आपको उस पर Bazel मॉड्यूल के तौर पर निर्भर रहना चाहिए. ऐसा तब होता है, जब वह Bzlmod को भी अपनाता है.
WORKSPACE
WORKSPACE के साथ, Bazel प्रोजेक्ट के सोर्स डाउनलोड करने के लिए,
http_archive
याgit_repository
रिपॉज़िटरी के नियमों का इस्तेमाल करना आम बात है.## 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 registry में उपलब्ध है, तो
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 मॉड्यूल की डिपेंडेंसी को अलग-अलग तरीकों से बदला जा सकता है.
ज़्यादा जानकारी के लिए, कृपया बदलाव सेक्शन पढ़ें.
उदाहरण रिपॉज़िटरी में, इस्तेमाल के कुछ उदाहरण देखे जा सकते हैं.
मॉड्यूल एक्सटेंशन की मदद से बाहरी डिपेंडेंसी फ़ेच करना
अगर आपकी डिपेंडेंसी कोई Bazel प्रोजेक्ट नहीं है या Bazel की किसी रजिस्ट्री में अब तक उपलब्ध नहीं है, तो इसे use_repo_rule
या मॉड्यूल एक्सटेंशन का इस्तेमाल करके जोड़ा जा सकता है.
WORKSPACE
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
फ़ाइल में ले जानी होगी. इससे माइग्रेशन की अवधि के दौरान, WORKSPACE और 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
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 में मौजूद मैक्रो के क्रम में बदलाव करना होगा. यह 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 के बिल्ड नियमों को यह पता लगाना होता है कि आपकी होस्ट मशीन पर कौनसी टूलचेन उपलब्ध हैं, तब वे रिपॉज़िटरी के नियमों का इस्तेमाल करके होस्ट मशीन की जांच करते हैं. साथ ही, टूलचेन की जानकारी को बाहरी रिपॉज़िटरी के तौर पर जनरेट करते हैं.
WORKSPACE
शेल टूलचेन का पता लगाने के लिए, रिपॉज़िटरी का यह नियम दिया गया है.
## 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 में रिपॉज़िटरी के नियम को लोड किया जा सकता है.
## 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
WORKSPACE की मदद से, टूलचेन को इन तरीकों से रजिस्टर किया जा सकता है.
.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()
इसके अलावा, टूलचेन को सीधे WORKSPACE फ़ाइल में रजिस्टर करें.
## 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
फ़ाइल में रजिस्टर किए गए टूलचेन और एक्ज़ीक्यूशन प्लैटफ़ॉर्म, टूलचेन चुनने के दौरान प्राथमिकता के इस क्रम का पालन करते हैं (सबसे ज़्यादा से सबसे कम):
- टूलचेन और एक्ज़ीक्यूशन प्लैटफ़ॉर्म, रूट मॉड्यूल की
MODULE.bazel
फ़ाइल में रजिस्टर किए गए हों. WORKSPACE
याWORKSPACE.bzlmod
फ़ाइल में रजिस्टर किए गए टूलचेन और एक्ज़ीक्यूशन प्लैटफ़ॉर्म.- टूलचेन और एक्ज़ीक्यूशन प्लैटफ़ॉर्म, उन मॉड्यूल से रजिस्टर किए जाते हैं जो रूट मॉड्यूल की (ट्रांज़िटिव) डिपेंडेंसी होते हैं.
WORKSPACE.bzlmod
का इस्तेमाल न करने पर:WORKSPACE
suffix में रजिस्टर किए गए टूलचेन.
स्थानीय रिपॉज़िटरी के बारे में जानकारी
आपको किसी डिपेंडेंसी को लोकल रिपॉज़िटरी के तौर पर तब शामिल करना पड़ सकता है, जब आपको डीबग करने के लिए डिपेंडेंसी के लोकल वर्शन की ज़रूरत हो या आपको अपने वर्कस्पेस में किसी डायरेक्ट्री को बाहरी रिपॉज़िटरी के तौर पर शामिल करना हो.
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 देखें. इसके बाद, मॉड्यूल एक्सटेंशन में, इससे जुड़े starlarklocal_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
से बदलें.- सलाह: टारगेट के बारे में काम की जानकारी पाने के लिए,
bazel query --output=build --noenable_bzlmod --enable_workspace [target]
कमांड का इस्तेमाल करें.
- सलाह: टारगेट के बारे में काम की जानकारी पाने के लिए,
इसके अलावा,
alias
नियम बनाएं का इस्तेमाल करेंकिसी पैकेज में यह टारगेट तय करें (जैसे,
//third_party
)## third_party/BUILD alias( name = "openssl", actual = "@my-ssl//src:openssl-lib", )
//external:openssl
के सभी इस्तेमाल को//third_party:openssl
से बदलें.
डेटा फ़ेच करना बनाम सिंक करना
फ़ेच और सिंक कमांड का इस्तेमाल, बाहरी रिपॉज़िटरी को स्थानीय तौर पर डाउनलोड करने और उन्हें अपडेट रखने के लिए किया जाता है. कभी-कभी, बिल्ड के लिए ज़रूरी सभी रिपॉज़िटरी फ़ेच करने के बाद, --nofetch
फ़्लैग का इस्तेमाल करके ऑफ़लाइन बिल्ड करने की अनुमति देने के लिए भी.
WORKSPACE
सिंक करने पर, सभी रिपॉज़िटरी या कॉन्फ़िगर किए गए रिपॉज़िटरी के किसी खास सेट के लिए, फ़ोर्स फ़ेच किया जाता है. वहीं, फ़ेच का इस्तेमाल सिर्फ़ किसी खास टारगेट के लिए फ़ेच करने के लिए किया जाता है.
Bzlmod
सिंक करने का निर्देश अब लागू नहीं होता. हालांकि, फ़ेच करने के लिए कई विकल्प उपलब्ध हैं. आपके पास टारगेट, रिपॉज़िटरी, कॉन्फ़िगर की गई रिपॉज़िटरी का सेट या डिपेंडेंसी रिज़ॉल्यूशन और मॉड्यूल एक्सटेंशन में शामिल सभी रिपॉज़िटरी को फ़ेच करने का विकल्प होता है. फ़ेच किए गए नतीजे को कैश मेमोरी में सेव किया जाता है. अगर आपको फ़ेच करने की प्रोसेस के दौरान,
--force
विकल्प को शामिल करके फ़ेच करने के लिए मजबूर करना है, तो ऐसा किया जा सकता है.
मैन्युअल तरीके से माइग्रेट करना
इस सेक्शन में, Bzlmod को मैन्युअल तरीके से माइग्रेट करने की प्रोसेस के बारे में काम की जानकारी और दिशा-निर्देश दिए गए हैं. माइग्रेशन की प्रोसेस को ज़्यादा ऑटोमेट करने के लिए, माइग्रेशन की सुझाई गई प्रोसेस सेक्शन देखें.
WORKSPACE में अपनी डिपेंडेंसी के बारे में जानना
माइग्रेशन का पहला चरण यह समझना है कि आपकी कौनसी डिपेंडेंसी हैं. ट्रांज़िटिव डिपेंडेंसी को अक्सर *_deps
मैक्रो के साथ लोड किया जाता है. इसलिए, WORKSPACE फ़ाइल में जोड़ी गई डिपेंडेंसी का पता लगाना मुश्किल हो सकता है.
वर्कस्पेस में मौजूद फ़ाइल के साथ बाहरी डिपेंडेंसी की जांच करना
अच्छी बात यह है कि फ़्लैग
--experimental_repository_resolved_file
आपकी मदद कर सकता है. यह फ़्लैग, आपकी पिछली Bazel कमांड में फ़ेच की गई सभी बाहरी डिपेंडेंसी की "लॉक फ़ाइल" जनरेट करता है. ज़्यादा जानकारी के लिए, यह ब्लॉग पोस्ट पढ़ें.
इसका इस्तेमाल दो तरीकों से किया जा सकता है:
कुछ टारगेट बनाने के लिए ज़रूरी बाहरी डिपेंडेंसी की जानकारी पाने के लिए.
bazel clean --expunge bazel build --nobuild --experimental_repository_resolved_file=resolved.bzl //foo:bar
WORKSPACE फ़ाइल में तय की गई सभी बाहरी डिपेंडेंसी की जानकारी फ़ेच करने के लिए.
bazel clean --expunge bazel sync --experimental_repository_resolved_file=resolved.bzl
bazel sync
कमांड की मदद से, WORKSPACE फ़ाइल में तय की गई सभी डिपेंडेंसी फ़ेच की जा सकती हैं. इनमें ये शामिल हैं:bind
के इस्तेमालregister_toolchains
औरregister_execution_platforms
के इस्तेमाल
हालांकि, अगर आपका प्रोजेक्ट क्रॉस प्लैटफ़ॉर्म है, तो हो सकता है कि कुछ प्लैटफ़ॉर्म पर Bazel सिंक काम न करे. ऐसा इसलिए, क्योंकि रिपॉज़िटरी के कुछ नियम सिर्फ़ उन प्लैटफ़ॉर्म पर ठीक से काम कर सकते हैं जिन पर वे काम करते हैं.
कमांड चलाने के बाद, आपको resolved.bzl
फ़ाइल में अपनी बाहरी डिपेंडेंसी की जानकारी मिलनी चाहिए.
bazel query
की मदद से बाहरी डिपेंडेंसी की जांच करना
आपको यह भी पता होगा कि bazel query
का इस्तेमाल, इन चीज़ों के लिए किया जा सकता है:
bazel query --output=build //external:<repo name>
यह ज़्यादा सुविधाजनक और तेज़ है. हालांकि, bazel query, बाहरी डिपेंडेंसी के वर्शन के बारे में गलत जानकारी दे सकती है. इसलिए, इसका इस्तेमाल करते समय सावधानी बरतें! Bzlmod की मदद से, बाहरी डिपेंडेंसी के बारे में क्वेरी करने और उनकी जांच करने के लिए, नया सबकमांड इस्तेमाल किया जाएगा.
पहले से मौजूद डिफ़ॉल्ट डिपेंडेंसी
--experimental_repository_resolved_file
से जनरेट की गई फ़ाइल की जांच करने पर, आपको कई ऐसी डिपेंडेंसी मिलेंगी जो आपके WORKSPACE में तय नहीं की गई हैं.
ऐसा इसलिए होता है, क्योंकि Bazel, उपयोगकर्ता की WORKSPACE फ़ाइल के कॉन्टेंट में प्रीफ़िक्स और सफ़िक्स जोड़ता है, ताकि कुछ डिफ़ॉल्ट डिपेंडेंसी को इंजेक्ट किया जा सके.ये डिपेंडेंसी आम तौर पर नेटिव नियमों (जैसे, @bazel_tools
, @platforms
, और @remote_java_tools
) के लिए ज़रूरी होती हैं. Bzlmod के साथ, इन डिपेंडेंसी को bazel_tools
नाम के बिल्ट-इन मॉड्यूल के साथ पेश किया जाता है. यह Bazel के हर दूसरे मॉड्यूल के लिए डिफ़ॉल्ट डिपेंडेंसी होती है.
धीरे-धीरे माइग्रेट करने के लिए हाइब्रिड मोड
Bzlmod और WORKSPACE, दोनों साथ-साथ काम कर सकते हैं. इससे, WORKSPACE फ़ाइल से Bzlmod में डिपेंडेंसी माइग्रेट करने की प्रोसेस धीरे-धीरे पूरी की जा सकती है.
WORKSPACE.bzlmod
माइग्रेशन के दौरान, Bazel का इस्तेमाल करने वाले लोगों को Bzlmod की सुविधा चालू और बंद करके, बिल्ड के बीच स्विच करना पड़ सकता है. WORKSPACE.bzlmod के साथ काम करने की सुविधा लागू की गई है, ताकि प्रोसेस को आसान बनाया जा सके.
WORKSPACE.bzlmod का सिंटैक्स, WORKSPACE फ़ाइल के सिंटैक्स जैसा ही होता है. Bzlmod चालू होने पर, अगर फ़ाइल फ़ोल्डर के रूट में WORKSPACE.bzlmod फ़ाइल भी मौजूद है, तो:
WORKSPACE.bzlmod
लागू हो जाता है औरWORKSPACE
के कॉन्टेंट को अनदेखा कर दिया जाता है.- WORKSPACE.bzlmod फ़ाइल में कोई प्रीफ़िक्स या सफ़िक्स नहीं जोड़ा गया है.
WORKSPACE.bzlmod फ़ाइल का इस्तेमाल करने से, माइग्रेशन की प्रोसेस आसान हो सकती है. इसकी वजह यह है कि:
- Bzlmod बंद होने पर, ओरिजनल WORKSPACE फ़ाइल से डिपेंडेंसी फ़ेच की जाती हैं.
- Bzlmod चालू होने पर, यह बेहतर तरीके से ट्रैक किया जा सकता है कि WORKSPACE.bzlmod के साथ कौनसी डिपेंडेंसी माइग्रेट करनी बाकी हैं.
रिपॉज़िटरी किसको दिखे
Bzlmod यह कंट्रोल कर सकता है कि किसी दी गई रिपॉज़िटरी से कौनसी अन्य रिपॉज़िटरी दिखें. ज़्यादा जानकारी के लिए, रिपॉज़िटरी के नाम और strict_deps देखें.
यहां अलग-अलग तरह की रिपॉज़िटरी के लिए, रिपॉज़िटरी की सेटिंग की खास जानकारी दी गई है. इसमें WORKSPACE को भी ध्यान में रखा गया है.
मुख्य रेपो से | Bazel मॉड्यूल के रिपॉज़िटरी से | मॉड्यूल एक्सटेंशन के रिपॉज़िटरी से | WORKSPACE के डेटा स्टोर करने की जगहों से | |
---|---|---|---|---|
मुख्य रेपो | दिख रहा है | अगर रूट मॉड्यूल, सीधे तौर पर निर्भरता है | अगर रूट मॉड्यूल, मॉड्यूल एक्सटेंशन को होस्ट करने वाले मॉड्यूल पर सीधे तौर पर निर्भर करता है | दिख रहा है |
Bazel मॉड्यूल रिपॉज़िटरी | डायरेक्ट डिपेंडेंसी | डायरेक्ट डिपेंडेंसी | मॉड्यूल एक्सटेंशन को होस्ट करने वाले मॉड्यूल के डायरेक्ट डिपेंडेंसी | रूट मॉड्यूल की डायरेक्ट डिपेंडेंसी |
मॉड्यूल एक्सटेंशन रिपॉज़िटरी | डायरेक्ट डिपेंडेंसी | डायरेक्ट डिपेंडेंसी | मॉड्यूल एक्सटेंशन को होस्ट करने वाले मॉड्यूल की डायरेक्ट डिपेंडेंसी + उसी मॉड्यूल एक्सटेंशन से जनरेट की गई सभी रिपो | रूट मॉड्यूल की डायरेक्ट डिपेंडेंसी |
Workspace Repos | सभी दिख रहे हैं | नहीं दिख रहा है | नहीं दिख रहा है | सभी दिख रहे हैं |
मैन्युअल तरीके से माइग्रेट करने की प्रोसेस
Bzlmod पर माइग्रेट करने की सामान्य प्रोसेस कुछ ऐसी हो सकती है:
- समझें कि WORKSPACE में आपकी कौनसी डिपेंडेंसी हैं.
- अपने प्रोजेक्ट की रूट डायरेक्ट्री में एक खाली MODULE.bazel फ़ाइल जोड़ें.
- WORKSPACE फ़ाइल के कॉन्टेंट को बदलने के लिए, एक खाली WORKSPACE.bzlmod फ़ाइल जोड़ें.
- Bzlmod चालू करके टारगेट बनाएं और देखें कि कौनसी रिपॉज़िटरी मौजूद नहीं है.
- हल की गई डिपेंडेंसी फ़ाइल में, मौजूद नहीं है ऐसी रिपॉज़िटरी की डेफ़िनिशन देखें.
- Bazel मॉड्यूल के तौर पर, छूटी हुई डिपेंडेंसी को मॉड्यूल एक्सटेंशन के ज़रिए जोड़ें या इसे WORKSPACE.bzlmod में छोड़ दें, ताकि बाद में माइग्रेट किया जा सके.
- चरण 4 पर वापस जाएं और तब तक दोहराएं, जब तक सभी डिपेंडेंसी उपलब्ध न हो जाएं.
Bazel मॉड्यूल पब्लिश करना
अगर आपका Bazel प्रोजेक्ट, दूसरे प्रोजेक्ट के लिए डिपेंडेंसी है, तो अपने प्रोजेक्ट को Bazel Central Registry में पब्लिश किया जा सकता है.
बीसीआर में अपने प्रोजेक्ट की जांच करने के लिए, आपको प्रोजेक्ट के सोर्स आर्काइव यूआरएल की ज़रूरत होगी. सोर्स संग्रह बनाते समय, इन बातों का ध्यान रखें:
पक्का करें कि संग्रह किसी खास वर्शन की ओर ले जा रहा हो.
बीसीआर, वर्शन वाले सोर्स आर्काइव ही स्वीकार कर सकता है. ऐसा इसलिए, क्योंकि Bzlmod को डिपेंडेंसी रिज़ॉल्यूशन के दौरान वर्शन की तुलना करनी होती है.
पक्का करें कि संग्रह का यूआरएल स्टेबल हो.
Bazel, हैश वैल्यू के हिसाब से संग्रह के कॉन्टेंट की पुष्टि करता है. इसलिए, आपको यह पक्का करना चाहिए कि डाउनलोड की गई फ़ाइल का चेकसम कभी न बदले. अगर यूआरएल GitHub से है, तो कृपया रिलीज़ पेज में रिलीज़ संग्रह बनाएं और उसे अपलोड करें. GitHub, मांग पर जनरेट किए गए सोर्स संग्रह के चेकसम की गारंटी नहीं देगा. कम शब्दों में कहें, तो
https://github.com/<org>/<repo>/releases/download/...
के फ़ॉर्म में मौजूद यूआरएल को स्थिर माना जाता है, जबकिhttps://github.com/<org>/<repo>/archive/...
को नहीं. ज़्यादा जानकारी के लिए, GitHub Archive Checksum Outage देखें.पक्का करें कि सोर्स ट्री, ओरिजनल रिपॉज़िटरी के लेआउट के मुताबिक हो.
अगर आपकी रिपॉज़िटरी बहुत बड़ी है और आपको गैर-ज़रूरी सोर्स हटाकर, कम साइज़ वाला डिस्ट्रिब्यूशन संग्रह बनाना है, तो कृपया पक्का करें कि हटाया गया सोर्स ट्री, ओरिजनल सोर्स ट्री का सबसेट हो. इससे असली उपयोगकर्ताओं के लिए,
archive_override
औरgit_override
की मदद से, मॉड्यूल को रिलीज़ नहीं किए गए वर्शन पर बदलना आसान हो जाता है.किसी सबडायरेक्ट्री में एक टेस्ट मॉड्यूल शामिल करें. यह मॉड्यूल, आपके सबसे सामान्य एपीआई की जांच करता है.
टेस्ट मॉड्यूल, Bazel प्रोजेक्ट होता है. इसमें अपना WORKSPACE और MODULE.bazel फ़ाइल होती है. यह फ़ाइल, सोर्स आर्काइव की सबडायरेक्ट्री में मौजूद होती है. यह पब्लिश किए जाने वाले असली मॉड्यूल पर निर्भर करती है. इसमें ऐसे उदाहरण या इंटिग्रेशन टेस्ट शामिल होने चाहिए जो आपके सबसे सामान्य एपीआई को कवर करते हों. इसे सेट अप करने का तरीका जानने के लिए, टेस्ट मॉड्यूल देखें.
जब आपके पास सोर्स संग्रह का यूआरएल तैयार हो जाए, तब बीसीआर में योगदान करने के दिशा-निर्देश का पालन करें. इसके बाद, GitHub पुल अनुरोध के साथ बीसीआर में अपना मॉड्यूल सबमिट करें.
हमारा सुझाव है कि आप अपनी रिपॉज़िटरी के लिए, Publish to BCR GitHub ऐप्लिकेशन सेट अप करें. इससे, BCR को मॉड्यूल सबमिट करने की प्रोसेस अपने-आप पूरी हो जाएगी.
सबसे सही तरीके
इस सेक्शन में, कुछ सबसे सही तरीके बताए गए हैं. बाहरी डिपेंडेंसी को बेहतर तरीके से मैनेज करने के लिए, आपको इन तरीकों का पालन करना चाहिए.
टारगेट को अलग-अलग पैकेज में बांटें, ताकि ग़ैर-ज़रूरी डिपेंडेंसी फ़ेच न की जा सकें.
#12835 देखें. इसमें बताया गया है कि टेस्ट के लिए, डेवलपमेंट से जुड़ी डिपेंडेंसी को उन टारगेट के लिए भी फ़ेच करना पड़ता है जिनकी उन्हें ज़रूरत नहीं होती. यह तरीका सिर्फ़ Bzlmod के लिए नहीं है. हालांकि, इन तरीकों का पालन करने से, डेवलपमेंट के लिए ज़रूरी डिपेंडेंसी को सही तरीके से तय करना आसान हो जाता है.
डेवलपमेंट डिपेंडेंसी तय करना
bazel_dep
और
use_extension
डायरेक्टिव के लिए, dev_dependency
एट्रिब्यूट को सही पर सेट किया जा सकता है, ताकि वे डिपेंडेंट प्रोजेक्ट में न फैलें. रूट मॉड्यूल के तौर पर, --ignore_dev_dependency
फ़्लैग का इस्तेमाल करके यह पुष्टि की जा सकती है कि आपके टारगेट, अब भी डेवलपमेंट डिपेंडेंसी और ओवरराइड के बिना बनाए जा रहे हैं या नहीं.
कम्यूनिटी का डेटा माइग्रेट करने की प्रोसेस
Bazel Central Registry पर जाकर, यह देखा जा सकता है कि आपकी डिपेंडेंसी पहले से उपलब्ध हैं या नहीं. इसके अलावा, माइग्रेट करने में आ रही समस्याओं के बारे में जानने के लिए, इस GitHub discussion में शामिल हों. यहां उन डिपेंडेंसी के बारे में पोस्ट करें जिनकी वजह से आपको माइग्रेट करने में समस्या आ रही है या उनके लिए अपवोट करें.
समस्याओं की शिकायत करना
Bzlmod से जुड़ी समस्याओं के बारे में जानने के लिए, कृपया Bazel GitHub की समस्या सूची देखें. अगर आपको कोई नई समस्या या सुविधा का अनुरोध करना है, तो बेझिझक करें. इससे माइग्रेशन की प्रोसेस को आगे बढ़ाने में मदद मिलेगी!