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=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 से शुरू होने वाली लाइनें खास होती हैं. इनका इस्तेमाल, अन्य "rc" फ़ाइलों को लोड करने के लिए किया जाता है. वर्कस्पेस रूट के हिसाब से कोई पाथ तय करने के लिए, import %workspace%/path/to/bazelrc लिखें.

import और try-import में यह अंतर है कि अगर import' की गई फ़ाइल मौजूद नहीं है या उसे पढ़ा नहीं जा सकता, तो Bazel काम नहीं करता. हालांकि, try-import' की गई फ़ाइल के लिए ऐसा नहीं होता.

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

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

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

ज़्यादातर 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 वगैरह का इस्तेमाल करना.

--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 को अनदेखा करना चाहिए. हर डायरेक्ट्री को एक लाइन में जोड़ें. एंट्री, वर्कस्पेस रूट के हिसाब से होती हैं.

ग्लोबल 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 को अनदेखा करने के लिए भी कहा जा सकता है.