bazelrc कॉन्फ़िगरेशन फ़ाइलें लिखें

Bazel कई विकल्प स्वीकार करता है. कुछ विकल्प अक्सर बदलते रहते हैं. जैसे, --subcommands. वहीं, कुछ विकल्प कई बिल्ड में एक जैसे रहते हैं. जैसे, --package_path. हर बिल्ड (और अन्य कमांड) के लिए, इन विकल्पों को बार-बार बताने से बचने के लिए, कॉन्फ़िगरेशन फ़ाइल में विकल्प बताए जा सकते हैं. इसे .bazelrc कहा जाता है.

.bazelrc फ़ाइलें कहां होती हैं?

Bazel, वैकल्पिक कॉन्फ़िगरेशन फ़ाइलों को यहां दिए गए क्रम में खोजता है. विकल्पों को इसी क्रम में समझा जाता है. इसलिए, अगर कोई टकराव होता है, तो बाद की फ़ाइलों में मौजूद विकल्प, पहले की फ़ाइल की वैल्यू को बदल सकते हैं. इनमें से कौनसी फ़ाइलें लोड की जाती हैं, यह कंट्रोल करने वाले सभी विकल्प, स्टार्टअप विकल्प होते हैं. इसका मतलब है कि ये विकल्प, bazel के बाद और कमांड (build, test वगैरह) से पहले होने चाहिए.

  1. सिस्टम आरसी फ़ाइल, जब तक --nosystem_rc मौजूद न हो.

    पाथ:

    • Linux/macOS/Unix पर: /etc/bazel.bazelrc
    • Windows पर: %ProgramData%\bazel.bazelrc

    अगर यह फ़ाइल मौजूद नहीं है, तो यह कोई गड़बड़ी नहीं है.

    अगर सिस्टम के तय किए गए किसी अन्य पाथ की ज़रूरत है, तो आपको कस्टम Bazel बाइनरी बनाना होगा. इसके लिए, BAZEL_SYSTEM_BAZELRC_PATH वैल्यू को //src/main/cpp:option_processor में बदलना होगा. सिस्टम के तय किए गए पाथ में, एनवायरमेंट वैरिएबल के रेफ़रंस शामिल हो सकते हैं. जैसे, Unix पर ${VAR_NAME} या Windows पर %VAR_NAME%.

  2. वर्कस्पेस आरसी फ़ाइल, जब तक --noworkspace_rc मौजूद न हो.

    पाथ: आपके वर्कस्पेस डायरेक्ट्री में .bazelrc (मुख्य MODULE.bazel फ़ाइल के बगल में).

    अगर यह फ़ाइल मौजूद नहीं है, तो यह कोई गड़बड़ी नहीं है.

  3. होम आरसी फ़ाइल, जब तक --nohome_rc मौजूद न हो.

    पाथ:

    • Linux/macOS/Unix पर: $HOME/.bazelrc
    • Windows पर: अगर %USERPROFILE%\.bazelrc मौजूद है, तो यह पाथ इस्तेमाल किया जाएगा. अगर यह मौजूद नहीं है, तो %HOME%/.bazelrc पाथ इस्तेमाल किया जाएगा

    अगर यह फ़ाइल मौजूद नहीं है, तो यह कोई गड़बड़ी नहीं है.

  4. एनवायरमेंट वैरिएबल आरसी फ़ाइल, अगर इसका पाथ BAZELRC एनवायरमेंट वैरिएबल के साथ सेट किया गया है.

    एनवायरमेंट वैरिएबल में, कॉमा से अलग किए गए कई पाथ शामिल हो सकते हैं.

  5. उपयोगकर्ता के तय की गई आरसी फ़ाइल, अगर इसे --bazelrc=file के साथ तय किया गया है

    यह फ़्लैग ज़रूरी नहीं है, लेकिन इसे एक से ज़्यादा बार भी तय किया जा सकता है.

    /dev/null से पता चलता है कि इसके बाद के सभी --bazelrc को अनदेखा किया जाएगा. यह उपयोगकर्ता की आरसी फ़ाइल की खोज को बंद करने के लिए काम का है. जैसे, रिलीज़ बिल्ड में.

    उदाहरण के लिए:

    --bazelrc=x.rc --bazelrc=y.rc --bazelrc=/dev/null --bazelrc=z.rc
    
    • x.rc और y.rc को पढ़ा जाता है.
    • पहले से मौजूद /dev/null की वजह से, z.rc को अनदेखा किया जाता है.

इस वैकल्पिक कॉन्फ़िगरेशन फ़ाइल के अलावा, Bazel एक ग्लोबल आरसी फ़ाइल भी खोजता है. ज़्यादा जानकारी के लिए, ग्लोबल bazelrc सेक्शन देखें.

.bazelrc का सिंटैक्स और मतलब

सभी UNIX "rc" फ़ाइलों की तरह, .bazelrc फ़ाइल भी एक टेक्स्ट फ़ाइल होती है. इसमें लाइन के हिसाब से व्याकरण होता है. खाली लाइनों और # (टिप्पणियों) से शुरू होने वाली लाइनों को अनदेखा किया जाता है. हर लाइन में शब्दों का क्रम होता है. इन्हें Bourne shell के नियमों के मुताबिक टोकन में बांटा जाता है.

आयात

import, try-import या try-import-if-bazel-version से शुरू होने वाली लाइनें खास होती हैं. इनका इस्तेमाल, अन्य "rc" फ़ाइलों को लोड करने के लिए किया जाता है. वर्कस्पेस रूट के मुकाबले कोई पाथ तय करने के लिए, import %workspace%/path/to/bazelrc लिखें.

अलग-अलग इंपोर्ट स्टेटमेंट के बीच का अंतर इस तरह है:

  • import - अगर imported की गई फ़ाइल मौजूद नहीं है या उसे पढ़ा नहीं जा सकता, तो Bazel काम नहीं करेगा
  • try-import - फ़ाइल को इंपोर्ट करने की कोशिश की जाएगी. हालांकि, import के उलट, अगर फ़ाइल मौजूद नहीं है या उसे पढ़ा नहीं जा सकता, तो Bazel काम नहीं करेगा.
  • try-import-if-bazel-version - यह try-import की तरह है. हालांकि, इंपोर्ट करने की कोशिश करने से पहले, Bazel के मौजूदा वर्शन की एक और शर्त की जांच की जाती है. सिंटैक्स के लिए, नीचे दी गई जानकारी देखें.

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

# Strictly greater than: used for post-release targeting
try-import-if-bazel-version >7.0.0 %workspace%/configs/post_v7.rc

# Greater than or equal to: commonly used for feature introduction
try-import-if-bazel-version >=6.0.0 %workspace%/configs/features.rc

# Strictly less than: used for deprecated flags removed in newer versions
try-import-if-bazel-version <7.0.0 %workspace%/configs/legacy.rc

# Less than or equal to: caps configuration to a specific version
try-import-if-bazel-version <=5.4.0 %workspace%/configs/v5_fixes.rc

# Exact match: hotfix for a specific broken release
try-import-if-bazel-version ==6.3.2 %workspace%/configs/hotfix_6.3.2.rc

# Not equal to: excludes broken version from standard config
try-import-if-bazel-version !=7.0.1 %workspace%/configs/standard.rc

एक और टिल्ड ऑपरेटर, पैच, माइनर, और मेजर वर्शन में बदलावों के लिए रेंज उपलब्ध कराता है:

# Equivalent to >=1.2.3 <1.3.0
try-import-if-bazel-version ~1.2.3 %workspace%/configs/1.2.3_flags.rc

# Equivalent to >=1.2.0 <1.3.0 (Same as 1.2.x)
try-import-if-bazel-version ~1.2 %workspace%/configs/1.2_flags.rc

# Equivalent to >=1.0.0 <2.0.0 (Same as 1.x)
try-import-if-bazel-version ~1 %workspace%/configs/v1_flags.rc

इंपोर्ट की प्राथमिकता:

  • इंपोर्ट की गई फ़ाइल में मौजूद विकल्पों को, इंपोर्ट स्टेटमेंट से पहले तय किए गए विकल्पों से ज़्यादा प्राथमिकता मिलती है.
  • इंपोर्ट स्टेटमेंट के बाद तय किए गए विकल्पों को, इंपोर्ट की गई फ़ाइल में मौजूद विकल्पों से ज़्यादा प्राथमिकता मिलती है.
  • बाद में इंपोर्ट की गई फ़ाइलों में मौजूद विकल्पों को, पहले इंपोर्ट की गई फ़ाइलों से ज़्यादा प्राथमिकता मिलती है.

विकल्पों की डिफ़ॉल्ट वैल्यू

bazelrc की ज़्यादातर लाइनों में, विकल्पों की डिफ़ॉल्ट वैल्यू तय की जाती हैं. हर लाइन का पहला शब्द यह तय करता है कि ये डिफ़ॉल्ट वैल्यू कब लागू होंगी:

  • startup: स्टार्टअप विकल्प. ये विकल्प, कमांड से पहले आते हैं. इनके बारे में bazel help startup_options में बताया गया है.
  • common: वे विकल्प जो Bazel के उन सभी कमांड पर लागू होने चाहिए जो उन्हें सपोर्ट करते हैं. अगर कोई कमांड, इस तरीके से तय किए गए किसी विकल्प को सपोर्ट नहीं करता है, तो उस विकल्प को अनदेखा कर दिया जाता है. हालांकि, यह तब तक मान्य होता है, जब तक वह Bazel के किसी अन्य कमांड के लिए मान्य हो. ध्यान दें कि यह सिर्फ़ विकल्प के नामों पर लागू होता है: अगर मौजूदा कमांड, तय किए गए नाम वाले किसी विकल्प को स्वीकार करता है, लेकिन तय की गई वैल्यू को सपोर्ट नहीं करता है, तो वह काम नहीं करेगा.
  • always: वे विकल्प जो Bazel के सभी कमांड पर लागू होते हैं. अगर कोई कमांड, इस तरीके से तय किए गए किसी विकल्प को सपोर्ट नहीं करता है, तो वह काम नहीं करेगा.
  • command: Bazel कमांड. जैसे, build या query, जिन पर विकल्प लागू होते हैं. ये विकल्प, तय किए गए कमांड से इनहेरिट करने वाले सभी कमांड पर भी लागू होते हैं. (उदाहरण के लिए, test, build से इनहेरिट करता है.)

इनमें से हर लाइन का इस्तेमाल एक से ज़्यादा बार किया जा सकता है. साथ ही, पहले शब्द के बाद आने वाले आर्ग्युमेंट को इस तरह जोड़ा जाता है जैसे वे किसी एक लाइन पर मौजूद हों. (CVS का इस्तेमाल करने वाले लोग, जो "स्विस आर्मी नाइफ़" कमांड-लाइन इंटरफ़ेस वाला एक और टूल है, उन्हें .cvsrc का सिंटैक्स एक जैसा लगेगा.) उदाहरण के लिए, इन लाइनों को:

build --test_tmpdir=/tmp/foo --verbose_failures
build --test_tmpdir=/tmp/bar

इस तरह जोड़ा जाता है:

build --test_tmpdir=/tmp/foo --verbose_failures --test_tmpdir=/tmp/bar

इसलिए, लागू होने वाले फ़्लैग --verbose_failures और --test_tmpdir=/tmp/bar हैं.

विकल्प की प्राथमिकता:

  • कमांड लाइन पर मौजूद विकल्पों को, आरसी फ़ाइलों में मौजूद विकल्पों से ज़्यादा प्राथमिकता मिलती है. उदाहरण के लिए, अगर किसी आरसी फ़ाइल में build -c opt लिखा है, लेकिन कमांड लाइन फ़्लैग -c dbg है, तो कमांड लाइन फ़्लैग को ज़्यादा प्राथमिकता मिलेगी.
  • आरसी फ़ाइल में, प्राथमिकता, खास मकसद के हिसाब से तय की जाती है: कम खास मकसद वाले कमांड की लाइनों के मुकाबले, ज़्यादा खास मकसद वाले कमांड की लाइनों को ज़्यादा प्राथमिकता मिलती है.

    खास मकसद के हिसाब से प्राथमिकता, इनहेरिटेंस से तय की जाती है. कुछ कमांड, अन्य कमांड से विकल्प इनहेरिट करते हैं. इससे, इनहेरिट करने वाला कमांड, बेस कमांड के मुकाबले ज़्यादा खास मकसद वाला बन जाता है. उदाहरण के लिए, test कमांड से इनहेरिट करता है. इसलिए, bazel build के सभी फ़्लैग, bazel test के लिए मान्य होते हैं. साथ ही, build की सभी लाइनें, bazel test पर भी लागू होती हैं. हालांकि, ऐसा तब तक होता है, जब तक उसी विकल्प के लिए कोई test लाइन न हो.build अगर आरसी फ़ाइल में यह लिखा है:

    test -c dbg --test_env=PATH
    build -c opt --verbose_failures

    तो bazel build //foo -c opt --verbose_failures का इस्तेमाल करेगा. वहीं, bazel test //foo --verbose_failures -c dbg --test_env=PATH का इस्तेमाल करेगा.

    इनहेरिटेंस (खास मकसद के हिसाब से प्राथमिकता) का ग्राफ़ यह है:

    • हर कमांड, common से इनहेरिट करता है
    • ये कमांड, build से इनहेरिट करते हैं (और build के मुकाबले ज़्यादा खास मकसद वाले होते हैं): test, run, clean, mobile-install, info, print_action, config, cquery, और aquery
    • coverage, fetch, और vendor, test से इनहेरिट करते हैं
  • एक ही कमांड के लिए, बराबर प्राथमिकता वाले दो विकल्पों को उस क्रम में पार्स किया जाता है जिस क्रम में वे फ़ाइल में दिखते हैं.

  • प्राथमिकता का यह नियम, फ़ाइल के क्रम से मेल नहीं खाता. इसलिए, अगर आरसी फ़ाइलों में प्राथमिकता के क्रम का पालन किया जाए, तो उन्हें पढ़ना आसान हो जाता है: सबसे ऊपर common विकल्प से शुरू करें और फ़ाइल के सबसे नीचे, सबसे खास मकसद वाले कमांड के साथ खत्म करें. इस तरह, विकल्पों को पढ़ने का क्रम वही होता है जिस क्रम में वे लागू होते हैं. यह ज़्यादा आसान है.

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

--config

विकल्पों की डिफ़ॉल्ट वैल्यू सेट करने के अलावा, आरसी फ़ाइल का इस्तेमाल विकल्पों को ग्रुप में बांटने और सामान्य ग्रुपिंग के लिए शॉर्टहैंड उपलब्ध कराने के लिए किया जा सकता है. इसके लिए, कमांड में :name सफ़िक्स जोड़ा जाता है. इन विकल्पों को डिफ़ॉल्ट रूप से अनदेखा किया जाता है. हालांकि, जब --config=name विकल्प मौजूद होता है, तब इन्हें शामिल किया जाता है. यह विकल्प, कमांड लाइन या किसी .bazelrc फ़ाइल में, किसी अन्य कॉन्फ़िगरेशन की परिभाषा के अंदर भी मौजूद हो सकता है. command:name से तय किए गए विकल्पों को, ऊपर बताए गए प्राथमिकता के क्रम में, सिर्फ़ लागू होने वाले कमांड के लिए बढ़ाया जाएगा.

--config=foo को आरसी फ़ाइलों में तय किए गए विकल्पों के लिए "इन-प्लेस" बढ़ाया जाता है. इससे, कॉन्फ़िगरेशन के लिए तय किए गए विकल्पों की प्राथमिकता वही होती है जो --config=foo विकल्प की थी.

यह सिंटैक्स, startup के इस्तेमाल पर लागू नहीं होता है ताकि स्टार्टअप विकल्प सेट किए जा सकें. .bazelrc में startup:config-name --some_startup_option सेट करने पर, इसे अनदेखा कर दिया जाएगा.

--enable_platform_specific_config

.bazelrc में, प्लैटफ़ॉर्म के हिसाब से कॉन्फ़िगरेशन को --enable_platform_specific_config का इस्तेमाल करके, अपने-आप चालू किया जा सकता है. उदाहरण के लिए, अगर होस्ट ओएस Linux है और build कमांड चलाया जाता है, तो build:linux कॉन्फ़िगरेशन अपने-आप चालू हो जाएगा. ओएस के लिए मान्य आइडेंटिफ़ायर, linux, macos, windows, freebsd, और openbsd हैं. इस फ़्लैग को चालू करना, Linux पर --config=linux, Windows पर --config=windows, macOS पर --config=macos, FreeBSD पर --config=freebsd, और OpenBSD पर --config=openbsd का इस्तेमाल करने के बराबर है.

--enable_platform_specific_config देखें.

उदाहरण

यहां ~/.bazelrc फ़ाइल का एक उदाहरण दिया गया है:

# Bob's Bazel option defaults

startup --host_jvm_args=-XX:-UseParallelGC
import /home/bobs_project/bazelrc
build --show_timestamps --keep_going --jobs 600
build --color=yes
query --keep_going

# Definition of --config=memcheck
build:memcheck --strip=never --test_timeout=3600

Bazel के व्यवहार को कंट्रोल करने वाली अन्य फ़ाइलें

.bazelignore

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

.bazelignore फ़ाइल में, ग्लोब सिमैंटिक की अनुमति नहीं है. Bazel 8 में, REPO.bazel फ़ाइल जोड़ी गई है. इससे एक और डायरेक्टिव, ignore_directories() का इस्तेमाल किया जा सकता है. यह अनदेखा करने के लिए डायरेक्ट्री की सूची लेता है. यह .bazelignore की तरह ही काम करता है, लेकिन इसमें ग्लोब सिमैंटिक का इस्तेमाल किया जा सकता है. #24203 देखें.

ग्लोबल bazelrc फ़ाइल

Bazel, वैकल्पिक bazelrc फ़ाइलों को इस क्रम में पढ़ता है:

  1. सिस्टम आरसी फ़ाइल, जो /etc/bazel.bazelrc पर मौजूद है.
  2. वर्कस्पेस आरसी फ़ाइल, जो $workspace/tools/bazel.rc पर मौजूद है.
  3. होम आरसी फ़ाइल, जो $HOME/.bazelrc पर मौजूद है

यहां दी गई हर bazelrc फ़ाइल के लिए, एक फ़्लैग मौजूद है.इसका इस्तेमाल करके, उन्हें बंद किया जा सकता है. जैसे, --nosystem_rc, --noworkspace_rc, --nohome_rc. --ignore_all_rc_files स्टार्टअप विकल्प पास करके, Bazel को सभी bazelrc को अनदेखा करने के लिए भी कहा जा सकता है.