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

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

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

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

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

    पाथ:

    • Linux/macOS/Unixes पर: /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 (मुख्य WORKSPACE फ़ाइल के बगल में).

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

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

    पाथ:

    • Linux/macOS/Unixes पर: $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 का सिंटैक्स, CVS के सिंटैक्स जैसा लगेगा.) उदाहरण के लिए, इन लाइनों को:

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

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

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

--config

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

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

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

उदाहरण

~/.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 फ़ाइलों को इस क्रम में पढ़ता है: - सिस्टम आरसी फ़ाइल, जो etc/bazel.bazelrc पर मौजूद है. - वर्कस्पेस आरसी फ़ाइल, जो $workspace/tools/bazel.rc पर मौजूद है. - होम आरसी फ़ाइल, जो $HOME/.bazelrc पर मौजूद है

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