फ़ंक्शन

विषय सूची

पैकेज

package(default_deprecation, default_testonly, default_visibility, features)

यह फ़ंक्शन उस मेटाडेटा के बारे में बताता है जो पैकेज में बाद के हर नियम पर लागू होता है. इसका इस्तेमाल किसी पैकेज (BUILD फ़ाइल) में ज़्यादा से ज़्यादा एक बार किया जाता है.

पैकेज() फ़ंक्शन को किसी भी नियम से पहले, फ़ाइल के सबसे ऊपर मौजूद सभी load() स्टेटमेंट के ठीक बाद कॉल किया जाना चाहिए.

तर्क

एट्रिब्यूट ब्यौरा
default_visibility

List of labels; optional

इस पैकेज में शामिल नियमों की डिफ़ॉल्ट तौर पर, 'किसको दिखे' की सेटिंग.

जब तक नियम के visibility एट्रिब्यूट में कुछ और न बताया गया हो, तब तक इस पैकेज में मौजूद हर नियम के लिए 'किसको दिखे' एट्रिब्यूट की वैल्यू तय की गई है. इस एट्रिब्यूट के सिंटैक्स के बारे में ज़्यादा जानकारी के लिए, किसको दिखे से जुड़ा दस्तावेज़ देखें. पैकेज डिफ़ॉल्ट रूप से दिखने की सेटिंग, exports_files पर लागू नहीं होती, जो डिफ़ॉल्ट रूप से सार्वजनिक होती है.

default_deprecation

String; optional

इस पैकेज में मौजूद सभी नियमों के लिए, डिफ़ॉल्ट deprecation मैसेज सेट करता है.

default_testonly

Boolean; optional; default is False except as noted

इस पैकेज में मौजूद सभी नियमों के लिए, डिफ़ॉल्ट testonly प्रॉपर्टी सेट करता है.

javatests से कम कीमत वाले पैकेज में, डिफ़ॉल्ट वैल्यू 1 है.

features

List strings; optional

इस BUILD फ़ाइल के सिमैंटिक पर असर डालने वाले अलग-अलग फ़्लैग सेट करता है.

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

उदाहरण

नीचे दिए गए एलान में बताया गया है कि इस पैकेज के नियम सिर्फ़ पैकेज ग्रुप //foo:target के सदस्यों को दिखते हैं. किसी नियम के लिए व्यक्तिगत तौर पर दिखने की जानकारी अगर मौजूद हो, तो इस स्पेसिफ़िकेशन को बदल दिया जाता है.
package(default_visibility = ["//foo:target"])

package_group

package_group(name, packages, includes)

यह फ़ंक्शन पैकेज के सेट को परिभाषित करता है और सेट के साथ एक लेबल जोड़ता है. इस लेबल का रेफ़रंस visibility एट्रिब्यूट में दिया जा सकता है.

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

दिया गया पैकेज ग्रुप में तब माना जाता है, जब वह packages एट्रिब्यूट से मेल खाता हो या वह पहले से ही includes एट्रिब्यूट में बताए गए किसी दूसरे पैकेज ग्रुप में मौजूद हो.

पैकेज ग्रुप तकनीकी तौर पर टारगेट किए जाते हैं, लेकिन नियमों के हिसाब से नहीं बनाए जाते. साथ ही, उनके पास 'किसको दिखे' की कोई सुरक्षा नहीं होती.

तर्क

एट्रिब्यूट ब्यौरा
name

Name; required

इस टारगेट के लिए एक खास नाम.

packages

List of strings; optional

इस सूची में, पैकेज की शून्य या उससे ज़्यादा खास जानकारी शामिल होती है.

पैकेज के स्पेसिफ़िकेशन की हर स्ट्रिंग में, इनमें से कोई एक फ़ॉर्म हो सकता है:

  1. पैकेज का पूरा नाम, जिसमें डेटा को स्टोर करने की जगह के बिना, डबल स्लैश से शुरू किया जाता है. उदाहरण के लिए, //foo/bar उस पैकेज के बारे में बताता है जिसमें यह नाम होता है. साथ ही, यह पैकेज ग्रुप वाली रिपॉज़िटरी में ही रहता है.
  2. जैसा ऊपर बताया गया है, लेकिन /... के आखिर में. उदाहरण के लिए, //foo/..., //foo के सेट और उसके सभी सबपैकेज के बारे में बताता है. //..., डेटा स्टोर करने की मौजूदा जगह में सभी पैकेज के बारे में बताता है.
  3. public या private स्ट्रिंग, किसी पैकेज के बारे में बताती हैं या कोई पैकेज नहीं के बारे में बताती हैं. (इस फ़ॉर्म के लिए, --incompatible_package_group_has_public_syntax फ़्लैग को सेट करना ज़रूरी है.)

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

पैकेज ग्रुप में ऐसा कोई भी पैकेज होता है जो कम से कम एक अच्छी खासियत से मेल खाता हो. हालांकि, पैकेज से जुड़ी किसी भी जानकारी से मेल न खाता हो उदाहरण के लिए, [//foo/..., -//foo/tests/...] वैल्यू में //foo के वे सभी सबपैकेज शामिल हैं जो //foo/tests के सबपैकेज नहीं हैं. (//foo ही शामिल है, जबकि //foo/tests में नहीं है.)

सार्वजनिक तौर पर दिखने वाले ऐप्लिकेशन के अलावा, डेटा स्टोर करने की मौजूदा जगह के बाहर, पैकेज की जानकारी देने का कोई और तरीका नहीं है.

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

ध्यान दें: Bazel 6.0 से पहले के वर्शन, //... के लिए public जैसा ही काम करता था. यह तरीका --incompatible_fix_package_group_reporoot_syntax के चालू होने पर ठीक हो जाता है, जो Bazel 6.0 के बाद डिफ़ॉल्ट होता है.

ध्यान दें: Bazel 6.0 से पहले, जब इस एट्रिब्यूट को bazel query --output=proto (या --output=xml) के हिस्से के तौर पर क्रम में लगाया जाता है, तो शुरुआत में लगने वाले स्लैश शामिल नहीं किए जाते थे. उदाहरण के लिए, //pkg/foo/..., \"pkg/foo/...\" के तौर पर आउटपुट करेगा. यह व्यवहार तब ठीक किया जाता है, जब --incompatible_package_group_includes_double_slash चालू होता है, जो Bazel 6.0 के बाद डिफ़ॉल्ट होता है.

includes

List of labels; optional

इसमें शामिल अन्य पैकेज ग्रुप.

इस एट्रिब्यूट में मौजूद लेबल से, दूसरे पैकेज ग्रुप के बारे में पता चलना चाहिए. बताए गए पैकेज ग्रुप में मौजूद पैकेज को इस पैकेज ग्रुप में शामिल किया जाता है. यह ट्रांज़िटिव है — अगर पैकेज ग्रुप a में पैकेज ग्रुप b और b में पैकेज ग्रुप c शामिल है, तो c में मौजूद हर पैकेज भी a का सदस्य होगा.

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

उदाहरण

package_group के इस एलान में, "ट्रॉपिकल" नाम के एक पैकेज ग्रुप के बारे में बताया गया है, जिसमें ट्रॉपिकल फल हैं.

package_group(
    name = "tropical",
    packages = [
        "//fruits/mango",
        "//fruits/orange",
        "//fruits/papaya/...",
    ],
)

नीचे दिए गए एलानों में, किसी काल्पनिक ऐप्लिकेशन के पैकेज ग्रुप के बारे में बताया गया है:

package_group(
    name = "fooapp",
    includes = [
        ":controller",
        ":model",
        ":view",
    ],
)

package_group(
    name = "model",
    packages = ["//fooapp/database"],
)

package_group(
    name = "view",
    packages = [
        "//fooapp/swingui",
        "//fooapp/webui",
    ],
)

package_group(
    name = "controller",
    packages = ["//fooapp/algorithm"],
)

exports_files

exports_files([label, ...], visibility, licenses)

exports_files() इस पैकेज से जुड़ी उन फ़ाइलों की सूची के बारे में बताता है जिन्हें दूसरे पैकेज में एक्सपोर्ट किया गया है.

किसी पैकेज के लिए बिल्ड फ़ाइल, सीधे तौर पर किसी दूसरे पैकेज की सोर्स फ़ाइलों का रेफ़रंस दे सकती है. हालांकि, ऐसा तब होता है, जब उन्हें साफ़ तौर पर exports_files() स्टेटमेंट के साथ एक्सपोर्ट किया गया हो. फ़ाइलों को देखने के बारे में ज़्यादा पढ़ें.

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

तर्क

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

उदाहरण

इस उदाहरण में, golden.txt को एक्सपोर्ट किया जाता है. यह test_data पैकेज की एक टेक्स्ट फ़ाइल होती है, ताकि दूसरे पैकेज भी इसका इस्तेमाल कर सकें. उदाहरण के लिए, जांच के data एट्रिब्यूट में.

# from //test_data/BUILD

exports_files(["golden.txt"])

ग्लोब

glob(include, exclude=[], exclude_directories=1, allow_empty=True)

Glob एक हेल्पर फ़ंक्शन है, जो कुछ खास पाथ पैटर्न से मेल खाने वाली सभी फ़ाइलें ढूंढता है और उनके पाथ की नई, बदली जा सकने वाली, क्रम से लगाई गई सूची दिखाता है. Glob सिर्फ़ अपने पैकेज में मौजूद फ़ाइलें खोजता है और सिर्फ़ सोर्स फ़ाइलों (जनरेट की गई फ़ाइलों या अन्य टारगेट नहीं) को खोजता है.

अगर फ़ाइल का पैकेज-रिलेटिव पाथ किसी भी include पैटर्न से मेल खाता है और किसी भी exclude पैटर्न से नहीं मैच करता है, तो सोर्स फ़ाइल का लेबल, नतीजे में शामिल किया जाता है.

include और exclude सूची में ऐसे पाथ पैटर्न शामिल हैं जो मौजूदा पैकेज से मिलते-जुलते हैं. हर पैटर्न में एक या ज़्यादा पाथ सेगमेंट हो सकते हैं. हमेशा की तरह, Unix पाथ के साथ, ये सेगमेंट / से अलग किए गए होते हैं. सेगमेंट में * वाइल्डकार्ड हो सकता है: यह, पाथ सेगमेंट की किसी भी सबस्ट्रिंग (यहां तक कि खाली सबस्ट्रिंग) से भी मेल खाता है. हालांकि, डायरेक्ट्री सेपरेटर / को शामिल नहीं किया जाता है. इस वाइल्डकार्ड को एक पाथ सेगमेंट में कई बार इस्तेमाल किया जा सकता है. इसके अलावा, ** वाइल्डकार्ड, शून्य या उससे ज़्यादा पूरे पाथ सेगमेंट से मैच कर सकता है. हालांकि, इसे स्टैंडअलोन पाथ सेगमेंट के तौर पर एलान करना ज़रूरी है.

उदाहरण:
  • foo/bar.txt, इस पैकेज में मौजूद foo/bar.txt फ़ाइल से पूरी तरह मेल खाता है
  • अगर फ़ाइल के आखिर में .txt आता है, तो foo/*.txt foo/ डायरेक्ट्री में मौजूद हर फ़ाइल से मेल खाता है. ऐसा तब तक होगा, जब तक foo/ कोई सबपैकेज न हो
  • foo/a*.htm*, foo/ डायरेक्ट्री की हर उस फ़ाइल को मैच करता है जो a से शुरू होती है. इसके बाद, एक आर्बिट्ररी स्ट्रिंग (खाली हो सकती है), फिर .htm होती है और इसके आखिर में दूसरी आर्बिट्ररी स्ट्रिंग होती है. जैसे, foo/axx.htm और foo/a.html या foo/axxx.html
  • **/a.txt, इस पैकेज की हर सबडायरेक्ट्री की हर a.txt फ़ाइल से मेल खाता है
  • **/bar/**/*.txt, इस पैकेज की हर सबडायरेक्ट्री में, हर .txt फ़ाइल से मैच करता है. ऐसा तब होता है, जब पाथ पर मौजूद कम से कम एक डायरेक्ट्री को bar नाम दिया जाता है, जैसे कि xxx/bar/yyy/zzz/a.txt या bar/a.txt (ध्यान रखें कि ** भी शून्य सेगमेंट से मेल खाता है) या bar/zzz/a.txt
  • ** इस पैकेज की हर सबडायरेक्ट्री की हर फ़ाइल से मेल खाता है
  • foo**/a.txt एक अमान्य पैटर्न है, क्योंकि ** को एक सेगमेंट के रूप में अपने-आप में होना चाहिए

अगर exclude_directories आर्ग्युमेंट चालू है (1 पर सेट है), तो टाइप डायरेक्ट्री की फ़ाइलें, नतीजों में शामिल नहीं होंगी (डिफ़ॉल्ट तौर पर 1).

अगर allow_empty आर्ग्युमेंट को False पर सेट किया गया है, तो glob फ़ंक्शन से गड़बड़ी हो जाएगी. ऐसा तब होगा, जब नतीजा खाली सूची हो.

इसकी कई अहम सीमाएं और सावधानियां हैं:

  1. glob(), BUILD फ़ाइल की जांच के दौरान चलता है. इसलिए, glob() सिर्फ़ आपके सोर्स ट्री की फ़ाइलों को मैच करता है. यह कभी जनरेट नहीं की जाती. अगर आपको कोई ऐसा टारगेट बनाना है जिसके लिए सोर्स और जनरेट की गई फ़ाइलें, दोनों ज़रूरी हों, तो आपको ग्लोब में, जनरेट की गई फ़ाइलों की एक खास सूची जोड़नी होगी. नीचे दिया गया उदाहरण देखें, जिसमें :mylib और :gen_java_srcs की जानकारी दी गई है.

  2. अगर किसी नियम का नाम, मैच होने वाली सोर्स फ़ाइल जैसा है, तो नियम फ़ाइल को "शैडो" कर देगा.

    इसे समझने के लिए, यह याद रखें कि glob(), पाथ की सूची दिखाता है. इसलिए, दूसरे नियमों के एट्रिब्यूट (जैसे, srcs = glob(["*.cc"])) में glob() का इस्तेमाल करने से, वैसा ही असर होता है जैसा कि मेल खाने वाले पाथ की साफ़ तौर पर सूची बनाने से होता है. उदाहरण के लिए, अगर glob() से ["Foo.java", "bar/Baz.java"] मिलता है, लेकिन "Foo.java" नाम के पैकेज में एक नियम है, जिसकी अनुमति है, लेकिन Bazel इसके बारे में चेतावनी देता है, तो glob() का उपभोक्ता, "Foo.java" फ़ाइल के बजाय "Foo.java" नियम (इसके आउटपुट) का इस्तेमाल करेगा. ज़्यादा जानकारी के लिए, GitHub की समस्या #10395 देखें.

  3. ग्लोब, सबडायरेक्ट्री की फ़ाइलों से मेल खा सकते हैं. सबडायरेक्ट्री के नाम वाइल्डकार्ड किए जा सकते हैं. हालांकि...
  4. लेबल को पैकेज की सीमा पार करने की अनुमति नहीं है और ग्लोब का इस्तेमाल, सबपैकेज में मौजूद फ़ाइलों से नहीं किया जा सकता.

    उदाहरण के लिए, अगर x/y पैकेज के तौर पर मौजूद है (x/y/BUILD के तौर पर या पैकेज पाथ पर किसी और जगह पर), तो पैकेज x में ग्लोब एक्सप्रेशन **/*.cc में x/y/z.cc शामिल नहीं है. इसका मतलब है कि ग्लोब एक्सप्रेशन का नतीजा BUILD फ़ाइलों की मौजूदगी पर निर्भर करता है. इसका मतलब है कि अगर x/y नाम का कोई पैकेज न हो या उसे --deleted_packages फ़्लैग का इस्तेमाल करके, 'मिटाया गया' के तौर पर मार्क किया गया हो, तो एक ही ग्लोब एक्सप्रेशन में x/y/z.cc शामिल होगा.

  5. ऊपर बताई गई पाबंदी, ग्लोब के सभी एक्सप्रेशन पर लागू होती है. इससे कोई फ़र्क़ नहीं पड़ता कि वे कौनसे वाइल्डकार्ड का इस्तेमाल करते हैं.
  6. . से शुरू होने वाली फ़ाइल नाम वाली छिपी हुई फ़ाइल को ** और * वाइल्डकार्ड, दोनों से पूरी तरह मैच किया जाता है. अगर आपको किसी छिपी हुई फ़ाइल को कंपाउंड पैटर्न से मैच करना है, तो पैटर्न . से शुरू होना चाहिए. उदाहरण के लिए, * और .*.txt, .foo.txt से मेल खाएंगे, लेकिन *.txt से नहीं. छिपी हुई डायरेक्ट्री का मिलान भी इसी तरह किया जाता है. छिपी हुई डायरेक्ट्री में ऐसी फ़ाइलें शामिल हो सकती हैं जिनकी इनपुट के तौर पर ज़रूरत नहीं है. इससे ग़ैर-ज़रूरी ग्लोब वाली फ़ाइलों और मेमोरी के इस्तेमाल की संख्या बढ़ सकती है. छिपी हुई डायरेक्ट्री को बाहर रखने के लिए, उन्हें "बाहर रखें" सूची में शामिल आर्ग्युमेंट में जोड़ें.
  7. "**" वाइल्डकार्ड में एक कोने वाला केस होता है: "**" पैटर्न, पैकेज की डायरेक्ट्री पाथ से मेल नहीं खाता. इसका मतलब है कि glob(["**"], exclude_directories = 0) उन सभी फ़ाइलों और डायरेक्ट्री से मैच करता है जो मौजूदा पैकेज की डायरेक्ट्री के तहत ट्रांज़िट के तौर पर इस्तेमाल की जाती हैं. हालांकि, हम सबपैकेज की डायरेक्ट्री में नहीं जा सकते. इस बारे में पिछला नोट देखें.

आम तौर पर, आपको ग्लोब पैटर्न के लिए सिर्फ़ '*' इस्तेमाल करने के बजाय, सही एक्सटेंशन (जैसे कि *.html) देने की कोशिश करनी चाहिए. नाम को बेहतर बनाने के लिए, इसे सेल्फ़ दस्तावेज़िंग कहते हैं. इससे यह पक्का किया जाता है कि गलती से बैकअप फ़ाइलों या emacs/vi/... फ़ाइलों को अपने-आप सेव होने से रोका न जाए.

बिल्ड के नियम बनाते समय, ग्लोब के एलिमेंट की गिनती की जा सकती है. इससे, उदाहरण के लिए, हर इनपुट के लिए अलग-अलग नियम जनरेट किए जा सकते हैं. नीचे एक्सपैंडेड ग्लोब का उदाहरण सेक्शन देखें.

ग्लोब के उदाहरण

इस डायरेक्ट्री की सभी JavaScript फ़ाइलों से बनी Java लाइब्रेरी और :gen_java_srcs नियम से जनरेट की गई सभी फ़ाइलें बनाएं.

java_library(
    name = "mylib",
    srcs = glob(["*.java"]) + [":gen_java_srcs"],
    deps = "...",
)

genrule(
    name = "gen_java_srcs",
    outs = [
        "Foo.java",
        "Bar.java",
    ],
    ...
)

प्रयोग वाली.txt फ़ाइल को छोड़कर, डायरेक्ट्री के testdata में सभी टेक्स्ट फ़ाइलें शामिल करें. ध्यान दें कि testdata की सबडायरेक्ट्री में मौजूद फ़ाइलों को शामिल नहीं किया जाएगा. अगर आपको उन फ़ाइलों को शामिल करना है, तो रिकर्सिव ग्लोब (**) का इस्तेमाल करें.

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(
        ["testdata/*.txt"],
        exclude = ["testdata/experimental.txt"],
    ),
)

बार-बार होने वाले ग्लोब के उदाहरण

यह टेस्ट, testdata डायरेक्ट्री में मौजूद सभी टेक्स्ट फ़ाइलों और उसकी सबडायरेक्ट्री (और उनकी सबडायरेक्ट्री वगैरह) पर निर्भर करेगा. BUILD फ़ाइल वाली सबडायरेक्ट्री को नज़रअंदाज़ किया जाता है. (ऊपर दी गई सीमाएं और चेतावनियां देखें.)

sh_test(
    name = "mytest",
    srcs = ["mytest.sh"],
    data = glob(["testdata/**/*.txt"]),
)

इस डायरेक्ट्री की सभी JavaScript फ़ाइलों और सबडायरेक्ट्री को छोड़कर, बाकी सभी सबडायरेक्ट्री से एक लाइब्रेरी बनाएं. इनके पाथ में, टेस्टिंग नाम की डायरेक्ट्री शामिल होती है. अगर संभव हो, तो इस पैटर्न से बचना चाहिए, क्योंकि इससे बिल्ड की संख्या कम हो सकती है और बिल्ड में लगने वाला समय बढ़ सकता है.

java_library(
    name = "mylib",
    srcs = glob(
        ["**/*.java"],
        exclude = ["**/testing/**"],
    ),
)

बड़े किए गए ग्लोब के उदाहरण

मौजूदा डायरेक्ट्री में *_test.cc के लिए अलग से एक ऐसा जेनरूल बनाएं जो फ़ाइल में मौजूद लाइनों की गिनती करता हो.

# Conveniently, the build language supports list comprehensions.
[genrule(
    name = "count_lines_" + f[:-3],  # strip ".cc"
    srcs = [f],
    outs = ["%s-linecount.txt" % f[:-3]],
    cmd = "wc -l $< >$@",
 ) for f in glob(["*_test.cc"])]

अगर ऊपर दी गई BUILD फ़ाइल, पैकेज //foo में है और पैकेज में इससे मेल खाने वाली तीन फ़ाइलें हैं, a_test.cc, b_test.cc, और c_test.cc और फिर चलती हैं bazel query '//foo:all' पर जनरेट किए गए सभी नियमों की सूची होगी:

$ bazel query '//foo:all' | sort
//foo:count_lines_a_test
//foo:count_lines_b_test
//foo:count_lines_c_test

चुनें

select(
    {conditionA: valuesA, conditionB: valuesB, ...},
    no_match_error = "custom message"
)

select() एक हेल्पर फ़ंक्शन है, जो नियम एट्रिब्यूट को कॉन्फ़िगर किया जा सकता है. यह करीब किसी भी एट्रिब्यूट असाइनमेंट की दाईं ओर मौजूद वर्शन को बदल सकता है. इसलिए, इसकी वैल्यू कमांड लाइन Bazel फ़्लैग पर निर्भर करती है. उदाहरण के लिए, इसका इस्तेमाल किसी खास प्लैटफ़ॉर्म की डिपेंडेंसी तय करने के लिए किया जा सकता है. इसके अलावा, अलग-अलग रिसॉर्स को एम्बेड करने के लिए भी इसका इस्तेमाल किया जा सकता है. यह इस बात पर निर्भर करता है कि कोई नियम "डेवलपर" बनाम "रिलीज़" मोड में बनाया गया है या नहीं.

बुनियादी इस्तेमाल इस तरह है:

sh_binary(
    name = "mytarget",
    srcs = select({
        ":conditionA": ["mytarget_a.sh"],
        ":conditionB": ["mytarget_b.sh"],
        "//conditions:default": ["mytarget_default.sh"]
    })
)

इससे, sh_binary के srcs एट्रिब्यूट को कॉन्फ़िगर किया जा सकता है. इसके लिए, लेबल की सूची में असाइन किए गए सामान्य असाइनमेंट को select कॉल से बदला जाता है. यह कॉन्फ़िगरेशन की शर्तों को, उनसे मेल खाने वाली वैल्यू के साथ मैप करता है. हर शर्त, config_setting या constraint_value का एक लेबल है, जो तब "मैच करता है", जब टारगेट का कॉन्फ़िगरेशन, वैल्यू के सही सेट से मैच करता है. इसके बाद, mytarget#srcs की वैल्यू वह हो जाएगी लेबल की सूची, जो मौजूदा लागू किए जाने वाले कोड से मेल खाती है.

ध्यान दें:

  • किसी भी बातचीत के लिए सिर्फ़ एक शर्त चुनी जाती है.
  • अगर एक से ज़्यादा शर्तें मेल खाती हैं और एक, दूसरी शर्तों की विशेषज्ञता है, तो विशेषज्ञता को प्राथमिकता दी जाती है. शर्त B को शर्त A की विशेषज्ञता तब माना जाता है, जब B में वे सभी फ़्लैग और कंस्ट्रेंट वैल्यू हों जो A के साथ-साथ कुछ दूसरे फ़्लैग या कंस्ट्रेंट वैल्यू भी हैं. इसका मतलब यह भी है कि विशेषज्ञता का रिज़ॉल्यूशन, ऑर्डर तैयार करने के लिए नहीं बनाया गया है, जैसा कि नीचे उदाहरण 2 में दिखाया गया है.
  • अगर एक से ज़्यादा शर्तें पूरी होती हैं और कोई एक, बाकी सभी स्थितियों के लिए विशेषज्ञता नहीं है, तो Bazel एक गड़बड़ी के साथ फ़ेल हो जाएगा.
  • अगर कोई दूसरी शर्त मेल नहीं खाती है, तो खास सूडो-लेबल //conditions:default को मैच माना जाता है. अगर यह शर्त लागू नहीं होती है, तो गड़बड़ी से बचने के लिए कोई दूसरा नियम मेल खाना चाहिए.
  • select को एक बड़े एट्रिब्यूट असाइनमेंट के अंदर एम्बेड किया जा सकता है. इसलिए, srcs = ["common.sh"] + select({ ":conditionA": ["myrule_a.sh"], ...}) और srcs = select({ ":conditionA": ["a.sh"]}) + select({ ":conditionB": ["b.sh"]}) मान्य एक्सप्रेशन हैं.
  • select ज़्यादातर एट्रिब्यूट के साथ काम करता है. हालांकि, यह सभी एट्रिब्यूट के साथ काम नहीं करता. काम न करने वाले एट्रिब्यूट को उनके दस्तावेज़ में nonconfigurable के तौर पर मार्क किया गया है.

    सबपैकेज

    subpackages(include, exclude=[], allow_empty=True)

    subpackages() एक हेल्पर फ़ंक्शन है. यह glob() की तरह ही होता है. इसमें फ़ाइलों और डायरेक्ट्री के बजाय, सबपैकेज शामिल होते हैं. यह पाथ पैटर्न, glob() वाले पैटर्न का ही इस्तेमाल करता है. साथ ही, यह ऐसे किसी भी सबपैकेज से मेल खा सकता है जो सीधे तौर पर लोड हो रही BUILD फ़ाइल का वंशज है. शामिल करने और बाहर रखने के पैटर्न की ज़्यादा जानकारी और उदाहरणों के लिए, ग्लोब देखें.

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

    उदाहरण

    इस उदाहरण में, पैकेज foo/BUILD के सभी डायरेक्ट सबपैकेज की सूची दी गई है

    # The following BUILD files exist:
    # foo/BUILD
    # foo/bar/baz/BUILD
    # foo/sub/BUILD
    # foo/sub/deeper/BUILD
    #
    # In foo/BUILD a call to
    subs = subpackages(include = ["**"])
    
    # results in subs == ["sub", "bar/baz"]
    #
    # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of
    # 'foo'
    

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