सामग्री
पैकेज
package(default_deprecation, default_package_metadata, default_testonly, default_visibility, features)
यह फ़ंक्शन, पैकेज के हर नियम पर लागू होने वाले मेटाडेटा के बारे में बताता है. इसका इस्तेमाल किसी पैकेज (BUILD फ़ाइल) में ज़्यादा से ज़्यादा एक बार किया जाता है.
मेटाडेटा के उस हिस्से के लिए जो पूरी रिपॉज़िटरी के हर नियम पर लागू होता है, अपनी रिपॉज़िटरी के रूट में मौजूद REPO.bazel
फ़ाइल में repo()
फ़ंक्शन का इस्तेमाल करें.
repo()
फ़ंक्शन, package()
फ़ंक्शन की तरह ही तर्क लेता है.
package() फ़ंक्शन को फ़ाइल में सबसे ऊपर मौजूद सभी load() स्टेटमेंट के ठीक बाद कॉल किया जाना चाहिए. साथ ही, इसे किसी भी नियम से पहले कॉल किया जाना चाहिए.
तर्क
एट्रिब्यूट | ब्यौरा |
---|---|
default_applicable_licenses |
|
default_visibility |
लेबल की सूची; डिफ़ॉल्ट वैल्यू इस पैकेज में, टॉप-लेवल के नियम टारगेट और सिंबॉलिक मैक्रो के दिखने की डिफ़ॉल्ट सेटिंग — यानी कि ऐसे टारगेट और सिंबॉलिक मैक्रो जिन्हें सिंबॉलिक मैक्रो के अंदर नहीं दिखाया जाता. अगर टारगेट या मैक्रो, इस एट्रिब्यूट के सिंटैक्स के बारे में ज़्यादा जानकारी के लिए, visibility का दस्तावेज़ देखें. पैकेज की डिफ़ॉल्ट विज़िबिलिटी, exports_files पर लागू नहीं होती. यह डिफ़ॉल्ट रूप से सार्वजनिक होती है. |
default_deprecation |
स्ट्रिंग; डिफ़ॉल्ट वैल्यू इस पैकेज में मौजूद सभी नियमों के लिए, डिफ़ॉल्ट
|
default_package_metadata |
लेबल की सूची; डिफ़ॉल्ट वैल्यू मेटाडेटा के टारगेट की डिफ़ॉल्ट सूची सेट करता है. यह सूची, पैकेज में मौजूद अन्य सभी टारगेट पर लागू होती है. ये आम तौर पर, ओएसएस पैकेज और लाइसेंस के एलान से जुड़े टारगेट होते हैं. उदाहरणों के लिए, rules_license देखें. |
default_testonly |
बूलियन; डिफ़ॉल्ट रूप से इस पैकेज में मौजूद सभी नियमों के लिए, डिफ़ॉल्ट
|
features |
स्ट्रिंग की सूची; डिफ़ॉल्ट वैल्यू यह BUILD फ़ाइल के सिमैंटिक पर असर डालने वाले अलग-अलग फ़्लैग सेट करता है. इस सुविधा का इस्तेमाल मुख्य तौर पर, बिल्ड सिस्टम पर काम करने वाले लोग करते हैं. वे इसका इस्तेमाल उन पैकेज को टैग करने के लिए करते हैं जिन्हें किसी खास तरह से हैंडल करने की ज़रूरत होती है. इसका इस्तेमाल तब तक न करें, जब तक कि बिल्ड सिस्टम पर काम करने वाला कोई व्यक्ति आपसे ऐसा करने के लिए न कहे. |
उदाहरण
नीचे दिए गए एलान से पता चलता है कि इस पैकेज में मौजूद नियम, सिर्फ़ पैकेज ग्रुप//foo:target
के सदस्यों को दिखते हैं. अगर किसी नियम के लिए, अलग-अलग तौर पर दिखने की सेटिंग तय की गई है, तो इस खास जानकारी के बजाय उस सेटिंग का इस्तेमाल किया जाता है.
package(default_visibility = ["//foo:target"])
package_group
package_group(name, packages, includes)
यह फ़ंक्शन, पैकेज का सेट तय करता है और सेट के साथ एक लेबल जोड़ता है. लेबल का रेफ़रंस, visibility
एट्रिब्यूट में दिया जा सकता है.
पैकेज ग्रुप का इस्तेमाल मुख्य रूप से, विज़िबिलिटी को कंट्रोल करने के लिए किया जाता है. सार्वजनिक तौर पर दिखने वाले टारगेट को सोर्स ट्री के हर पैकेज से रेफ़रंस किया जा सकता है. निजी तौर पर दिखने वाले टारगेट को सिर्फ़ उसके पैकेज में रेफ़रंस किया जा सकता है. सब-पैकेज में नहीं. इन दोनों स्थितियों के बीच, टारगेट किए गए पैकेज के साथ-साथ एक या उससे ज़्यादा पैकेज ग्रुप में शामिल पैकेज का ऐक्सेस भी दिया जा सकता है. 'किसको दिखे' सेटिंग के बारे में ज़्यादा जानकारी पाने के लिए, किसको दिखे एट्रिब्यूट देखें.
किसी पैकेज को ग्रुप में तब माना जाता है, जब वह packages
एट्रिब्यूट से मेल खाता हो या packages
एट्रिब्यूट में बताए गए किसी दूसरे पैकेज ग्रुप में पहले से मौजूद हो.includes
पैकेज ग्रुप तकनीकी तौर पर टारगेट होते हैं, लेकिन इन्हें नियमों के हिसाब से नहीं बनाया जाता. साथ ही, ये खुद किसी भी तरह से विज़िबिलिटी से जुड़ी सुरक्षा नहीं देते.
तर्क
एट्रिब्यूट | ब्यौरा |
---|---|
name |
नाम; ज़रूरी है इस टारगेट के लिए यूनीक नाम. |
packages |
स्ट्रिंग की सूची; डिफ़ॉल्ट वैल्यू शून्य या उससे ज़्यादा पैकेज स्पेसिफ़िकेशन की सूची. हर पैकेज स्पेसिफ़िकेशन स्ट्रिंग, इनमें से किसी एक फ़ॉर्म में हो सकती है:
इसके अलावा, पैकेज की जानकारी के पहले दो टाइप में पैकेज ग्रुप में ऐसा कोई भी पैकेज शामिल होता है जो कम से कम एक पॉज़िटिव स्पेसिफ़िकेशन से मेल खाता हो और किसी भी नेगेटिव स्पेसिफ़िकेशन से मेल न खाता हो
उदाहरण के लिए, सार्वजनिक तौर पर दिखने के अलावा, मौजूदा रिपॉज़िटरी के बाहर के पैकेज सीधे तौर पर तय करने का कोई तरीका नहीं है. अगर यह एट्रिब्यूट मौजूद नहीं है, तो इसका मतलब है कि इसे खाली सूची पर सेट किया गया है. इसका मतलब यह भी है कि इसे सिर्फ़ ध्यान दें: Bazel 6.0 से पहले, ध्यान दें: Bazel 6.0 से पहले, जब इस एट्रिब्यूट को |
includes |
लेबल की सूची; डिफ़ॉल्ट वैल्यू इस पैकेज ग्रुप में शामिल अन्य पैकेज ग्रुप. इस एट्रिब्यूट में मौजूद लेबल, दूसरे पैकेज ग्रुप के होने चाहिए.
रेफ़र किए गए पैकेज ग्रुप में मौजूद पैकेज, इस पैकेज ग्रुप का हिस्सा माने जाते हैं. यह ट्रांज़िटिव है. इसका मतलब है कि अगर पैकेज ग्रुप पैकेज के स्पेसिफ़िकेशन को शामिल न करने वाले फ़िल्टर के साथ इसका इस्तेमाल करने पर, ध्यान दें कि हर ग्रुप के लिए पैकेज का सेट, सबसे पहले अलग-अलग तरीके से कैलकुलेट किया जाता है. इसके बाद, नतीजों को एक साथ जोड़ दिया जाता है. इसका मतलब है कि एक ग्रुप में शामिल नहीं किए गए स्पेसिफ़िकेशन का असर, दूसरे ग्रुप में शामिल स्पेसिफ़िकेशन पर नहीं पड़ता. |
उदाहरण
यहां दिए गए 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()
इस पैकेज से जुड़ी उन फ़ाइलों की सूची दिखाता है जिन्हें दूसरे पैकेज में एक्सपोर्ट किया जाता है.
किसी पैकेज की BUILD फ़ाइल, सिर्फ़ ऐसे सोर्स फ़ाइलों को सीधे तौर पर रेफ़र कर सकती है जो किसी दूसरे पैकेज से जुड़ी हों. हालांकि, ऐसा तब ही किया जा सकता है, जब उन्हें exports_files()
स्टेटमेंट के साथ एक्सपोर्ट किया गया हो. फ़ाइलों के दिखने के बारे में ज़्यादा जानें.
लेगसी वर्शन में, नियम के इनपुट के तौर पर इस्तेमाल की गई फ़ाइलें भी डिफ़ॉल्ट रूप से दिखने की सेटिंग के साथ एक्सपोर्ट की जाती हैं. ऐसा तब तक होता है, जब तक फ़्लैग --incompatible_no_implicit_file_export
को फ़्लिप नहीं किया जाता. हालांकि, इस तरीके पर भरोसा नहीं करना चाहिए और इसे तुरंत बंद कर देना चाहिए.
तर्क
आर्ग्युमेंट, मौजूदा पैकेज में मौजूद फ़ाइलों के नामों की सूची होती है. फ़ाइलों को दिखाने के लिए, यह भी तय किया जा सकता है कि उन्हें कौन देख सकता है. इस मामले में, फ़ाइलें सिर्फ़ उन लोगों को दिखेंगी जिन्हें आपने चुना है. अगर फ़ाइलों के दिखने की सेटिंग नहीं दी गई है, तो वे हर पैकेज को दिखेंगी. भले ही, package
फ़ंक्शन में पैकेज के लिए डिफ़ॉल्ट रूप से फ़ाइलों के दिखने की सेटिंग दी गई हो. लाइसेंस की जानकारी भी दी जा सकती है.
उदाहरण
यहां दिए गए उदाहरण में, test_data
पैकेज से golden.txt
टेक्स्ट फ़ाइल को एक्सपोर्ट किया गया है, ताकि दूसरे पैकेज इसका इस्तेमाल कर सकें. उदाहरण के लिए, टेस्ट के data
एट्रिब्यूट में.
# from //test_data/BUILD exports_files(["golden.txt"])
glob
glob(include, exclude=[], exclude_directories=1, allow_empty=True)
Glob एक हेल्पर फ़ंक्शन है. यह कुछ पाथ पैटर्न से मेल खाने वाली सभी फ़ाइलों को ढूंढता है. साथ ही, उनके पाथ की नई, बदली जा सकने वाली, और क्रम से लगाई गई सूची दिखाता है. Glob सिर्फ़ अपने पैकेज में मौजूद फ़ाइलों को खोजता है. साथ ही, यह सिर्फ़ सोर्स फ़ाइलों को खोजता है. यह जनरेट की गई फ़ाइलों या अन्य टारगेट को नहीं खोजता.
अगर किसी सोर्स फ़ाइल का पैकेज-रिलेटिव पाथ, include
पैटर्न में से किसी एक से मेल खाता है और exclude
पैटर्न में से किसी से भी मेल नहीं खाता है, तो नतीजे में उस फ़ाइल का लेबल शामिल किया जाता है.
include
और exclude
सूचियों में, पाथ पैटर्न शामिल होते हैं. ये पैटर्न, मौजूदा पैकेज के हिसाब से होते हैं. हर पैटर्न में एक या उससे ज़्यादा पाथ सेगमेंट हो सकते हैं. Unix पाथ की तरह ही, इन सेगमेंट को /
से अलग किया जाता है. पैटर्न में मौजूद सेगमेंट का मिलान, पाथ के सेगमेंट से किया जाता है. सेगमेंट में *
वाइल्डकार्ड शामिल हो सकता है: यह पाथ सेगमेंट में मौजूद किसी भी सबस्ट्रिंग (खाली सबस्ट्रिंग भी) से मेल खाता है. हालांकि, इसमें डायरेक्ट्री सेपरेटर /
शामिल नहीं होता. इस वाइल्डकार्ड का इस्तेमाल, एक पाथ सेगमेंट में कई बार किया जा सकता है. इसके अलावा, **
वाइल्डकार्ड, पाथ के शून्य या उससे ज़्यादा पूरे सेगमेंट से मेल खा सकता है. हालांकि, इसे पाथ के अलग सेगमेंट के तौर पर घोषित किया जाना चाहिए.
foo/bar.txt
, इस पैकेज में मौजूदfoo/bar.txt
फ़ाइल से पूरी तरह मेल खाता है. हालांकि, ऐसा तब नहीं होता, जबfoo/
कोई सबपैकेज हो- अगर फ़ाइल
.txt
से खत्म होती है, तोfoo/*.txt
,foo/
डायरेक्ट्री में मौजूद हर फ़ाइल से मेल खाता है. हालांकि, ऐसा तब नहीं होता, जबfoo/
कोई सबपैकेज हो foo/a*.htm*
,foo/
डायरेक्ट्री में मौजूद हर उस फ़ाइल से मैच करता है जोa
से शुरू होती है. इसके बाद, इसमें कोई भी स्ट्रिंग (खाली हो सकती है) होती है. इसके बाद, इसमें.htm
होता है और यह किसी अन्य स्ट्रिंग से खत्म होती है (जब तक किfoo/
कोई सबपैकेज न हो). जैसे,foo/axx.htm
औरfoo/a.html
याfoo/axxx.html
foo/*
,foo/
डायरेक्ट्री में मौजूद हर फ़ाइल से मेल खाता है. हालांकि, अगरfoo/
कोई सबपैकेज है, तो ऐसा नहीं होगा. यहfoo
डायरेक्ट्री से मेल नहीं खाता है. भले ही,exclude_directories
को 0 पर सेट किया गया होfoo/**
, पैकेज की पहली लेवल की सबडायरेक्ट्रीfoo/
के तहत, हर नॉन-सबपैकेज सबडायरेक्ट्री में मौजूद हर फ़ाइल से मेल खाता है; अगरexclude_directories
को 0 पर सेट किया जाता है, तोfoo
डायरेक्ट्री भी पैटर्न से मेल खाती है; इस मामले में,**
को शून्य पाथ सेगमेंट से मेल खाने वाला माना जाता है**/a.txt
, इस पैकेज की डायरेक्ट्री में मौजूदa.txt
फ़ाइलों के साथ-साथ, नॉन-सबपैकेज सबडायरेक्ट्री से भी मेल खाता है.**/bar/**/*.txt
इस पैकेज की हर नॉन-सबपैकेज सबडायरेक्ट्री में मौजूद हर.txt
फ़ाइल से मेल खाता है. हालांकि, ऐसा तब होता है, जब नतीजे के तौर पर मिले पाथ में कम से कम एक डायरेक्ट्री का नामbar
हो. जैसे,xxx/bar/yyy/zzz/a.txt
याbar/a.txt
(ध्यान रखें कि**
भी शून्य सेगमेंट से मेल खाता है) याbar/zzz/a.txt
**
इस पैकेज की हर सबडायरेक्ट्री में मौजूद हर फ़ाइल से मेल खाता हैfoo**/a.txt
एक अमान्य पैटर्न है, क्योंकि**
को एक सेगमेंट के तौर पर अलग से इस्तेमाल किया जाना चाहिएfoo/
एक अमान्य पैटर्न है, क्योंकि/
के बाद तय किया गया दूसरा सेगमेंट एक खाली स्ट्रिंग है
अगर exclude_directories
आर्ग्युमेंट चालू है (1 पर सेट है), तो नतीजे में डायरेक्ट्री टाइप की फ़ाइलें शामिल नहीं की जाएंगी (डिफ़ॉल्ट रूप से 1 पर सेट होता है).
अगर allow_empty
आर्ग्युमेंट को False
पर सेट किया जाता है, तो अगर नतीजे में खाली सूची मिलती है, तो glob
फ़ंक्शन गड़बड़ी दिखाएगा.
इस सुविधा से जुड़ी कुछ ज़रूरी सीमाएं और चेतावनियां हैं:
-
glob()
, BUILD फ़ाइल का आकलन करते समय चलता है. इसलिए,glob()
सिर्फ़ आपके सोर्स ट्री में मौजूद फ़ाइलों से मेल खाता है, जनरेट की गई फ़ाइलों से कभी नहीं. अगर आपको ऐसा टारगेट बनाना है जिसके लिए सोर्स और जनरेट की गई, दोनों तरह की फ़ाइलों की ज़रूरत है, तो आपको ग्लोब में जनरेट की गई फ़ाइलों की सूची जोड़नी होगी.:mylib
और:gen_java_srcs
के साथ नीचे दिया गया उदाहरण देखें. -
अगर किसी नियम का नाम, मैच की गई सोर्स फ़ाइल के नाम जैसा है, तो नियम फ़ाइल को "शैडो" करेगा.
इसे समझने के लिए, याद रखें कि
glob()
, पाथ की सूची दिखाता है. इसलिए,glob()
का इस्तेमाल दूसरे नियमों के एट्रिब्यूट (जैसे किsrcs = glob(["*.cc"])
) में करने से, मैच किए गए पाथ को साफ़ तौर पर लिस्ट करने जैसा ही असर होता है. उदाहरण के लिए, अगरglob()
से["Foo.java", "bar/Baz.java"]
मिलता है, लेकिन पैकेज में "Foo.java" नाम का एक नियम भी है (जिसे अनुमति है, हालांकि Bazel इसके बारे में चेतावनी देता है), तोglob()
का इस्तेमाल करने वाला व्यक्ति, "Foo.java" फ़ाइल के बजाय "Foo.java" नियम (इसके आउटपुट) का इस्तेमाल करेगा. ज़्यादा जानकारी के लिए, GitHub की समस्या #10395 देखें. - ग्लोब, सबडायरेक्ट्री में मौजूद फ़ाइलों से मैच कर सकते हैं. साथ ही, सबडायरेक्ट्री के नामों में वाइल्डकार्ड का इस्तेमाल किया जा सकता है. हालांकि...
-
लेबल को पैकेज की सीमा से बाहर जाने की अनुमति नहीं है. साथ ही, glob सबपैकेज में मौजूद फ़ाइलों से मेल नहीं खाता.
उदाहरण के लिए, अगर
x/y
पैकेज के तौर पर मौजूद है (चाहेx/y/BUILD
के तौर पर हो या पैकेज-पाथ पर कहीं और), तो पैकेजx
में मौजूद ग्लोब एक्सप्रेशन**/*.cc
मेंx/y/z.cc
शामिल नहीं होगा. इसका मतलब है कि ग्लोब एक्सप्रेशन का नतीजा, BUILD फ़ाइलों के मौजूद होने पर निर्भर करता है. इसका मतलब यह है कि अगरx/y/z.cc
नाम का कोई पैकेज मौजूद नहीं है या उसे --deleted_packages फ़्लैग का इस्तेमाल करके मिटा दिया गया है, तो वही ग्लोब एक्सप्रेशनx/y/z.cc
को शामिल करेगा.x/y
- ऊपर दी गई पाबंदी, सभी ग्लोब एक्सप्रेशन पर लागू होती है. भले ही, वे किसी भी वाइल्डकार्ड का इस्तेमाल करें.
-
.
से शुरू होने वाले नाम वाली छिपी हुई फ़ाइल,**
और*
, दोनों वाइल्डकार्ड से पूरी तरह मैच होती है. अगर आपको किसी छिपी हुई फ़ाइल को कंपाउंड पैटर्न से मैच करना है, तो आपका पैटर्न.
से शुरू होना चाहिए. उदाहरण के लिए,*
और.*.txt
,.foo.txt
से मैच करेंगे, लेकिन*.txt
मैच नहीं करेगा. छुपाई गई डायरेक्ट्री का मिलान भी इसी तरह किया जाता है. छिपी हुई डायरेक्ट्री में ऐसी फ़ाइलें हो सकती हैं जिनकी इनपुट के तौर पर ज़रूरत नहीं होती. इससे, बिना वजह ग्लोब की गई फ़ाइलों की संख्या और मेमोरी की खपत बढ़ सकती है. छिपी हुई डायरेक्ट्री को बाहर रखने के लिए, उन्हें "exclude" लिस्ट आर्ग्युमेंट में जोड़ें. -
"**" वाइल्डकार्ड का एक कॉर्नर केस है: पैटर्न
"**"
, पैकेज के डायरेक्ट्री पाथ से मेल नहीं खाता. इसका मतलब है किglob(["**"], exclude_directories = 0)
, मौजूदा पैकेज की डायरेक्ट्री में मौजूद सभी फ़ाइलों और डायरेक्ट्री से मेल खाता है. हालांकि, यह सबपैकेज की डायरेक्ट्री में नहीं जाता. इसके बारे में पिछली टिप्पणी देखें.
आम तौर पर, आपको ग्लोब पैटर्न के लिए, '*' का इस्तेमाल करने के बजाय, सही एक्सटेंशन (जैसे कि *.html) देने की कोशिश करनी चाहिए. ज़्यादा जानकारी देने वाले नाम से, फ़ाइल के बारे में पता चलता है. साथ ही, इससे यह पक्का होता है कि बैकअप फ़ाइलों या Emacs/vi/... की अपने-आप सेव होने वाली फ़ाइलों से गलती से मैच न हो जाए.
बिल्ड के नियम लिखते समय, ग्लोब के एलिमेंट की गिनती की जा सकती है. इससे हर इनपुट के लिए अलग-अलग नियम जनरेट किए जा सकते हैं. नीचे दिया गया ग्लोब के उदाहरण का बड़ा किया गया वर्शन सेक्शन देखें.
Glob के उदाहरण
इस डायरेक्ट्री में मौजूद सभी Java फ़ाइलों और :gen_java_srcs
नियम से जनरेट हुई सभी फ़ाइलों से बनी Java लाइब्रेरी बनाएं.
java_library( name = "mylib", srcs = glob(["*.java"]) + [":gen_java_srcs"], deps = "...", ) genrule( name = "gen_java_srcs", outs = [ "Foo.java", "Bar.java", ], ... )
testdata डायरेक्ट्री में मौजूद सभी txt फ़ाइलों को शामिल करें. हालांकि, experimental.txt को शामिल न करें. ध्यान दें कि testdata की सबडायरेक्ट्री में मौजूद फ़ाइलें शामिल नहीं की जाएंगी. अगर आपको उन फ़ाइलों को शामिल करना है, तो रिकर्सिव ग्लोब (**) का इस्तेमाल करें.
sh_test( name = "mytest", srcs = ["mytest.sh"], data = glob( ["testdata/*.txt"], exclude = ["testdata/experimental.txt"], ), )
बार-बार होने वाले ग्लोब के उदाहरण
टेस्ट को testdata डायरेक्ट्री और उसकी किसी भी सबडायरेक्ट्री (और उनकी सबडायरेक्ट्री वगैरह) में मौजूद सभी txt फ़ाइलों पर निर्भर बनाएं. BUILD फ़ाइल वाली सबडाइरेक्ट्री को अनदेखा किया जाता है. (ऊपर दी गई सीमाएं और पाबंदियां देखें.)
sh_test( name = "mytest", srcs = ["mytest.sh"], data = glob(["testdata/**/*.txt"]), )
इस डायरेक्ट्री और सभी सबडायरेक्ट्री में मौजूद सभी Java फ़ाइलों से एक लाइब्रेरी बनाएं. हालांकि, उन सबडायरेक्ट्री को छोड़कर जिनके पाथ में टेस्टिंग नाम की डायरेक्ट्री शामिल है. जहां तक हो सके, इस पैटर्न का इस्तेमाल नहीं करना चाहिए, क्योंकि इससे बिल्ड की इंक्रीमेंटैलिटी कम हो सकती है. इसलिए, बिल्ड के समय में बढ़ोतरी हो सकती है.
java_library( name = "mylib", srcs = glob( ["**/*.java"], exclude = ["**/testing/**"], ), )
ग्लोब के उदाहरणों को बड़ा किया गया
मौजूदा डायरेक्ट्री में *_test.cc के लिए एक अलग genrule बनाएं. यह फ़ाइल में मौजूद लाइनों की संख्या गिनेगा.
# 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"] }) )
इससे srcs
एट्रिब्यूट को कॉन्फ़िगर किया जा सकता है. इसके लिए, इसके सामान्य लेबल की सूची असाइनमेंट को select
कॉल से बदलें. यह कॉल, कॉन्फ़िगरेशन की शर्तों को मैच करने वाली वैल्यू पर मैप करता है.sh_binary
हर शर्त, config_setting
या constraint_value
का लेबल रेफ़रंस होती है. अगर टारगेट का कॉन्फ़िगरेशन, वैल्यू के अनुमानित सेट से मेल खाता है, तो यह "मेल खाती है". इसके बाद, mytarget#srcs
की वैल्यू वह लेबल लिस्ट बन जाती है जो मौजूदा इनवोकेशन से मेल खाती है.
ध्यान दें:
- किसी भी इनवोकेशन पर, सिर्फ़ एक शर्त चुनी जाती है.
- अगर कई शर्तें मिलती हैं और उनमें से एक शर्त, दूसरी शर्तों की स्पेशलाइज़ेशन है, तो स्पेशलाइज़ेशन वाली शर्त को प्राथमिकता दी जाती है. शर्त B को शर्त A का स्पेशलाइज़ेशन तब माना जाता है, जब B में A के सभी फ़्लैग और कंस्ट्रेंट वैल्यू के साथ-साथ कुछ अतिरिक्त फ़्लैग या कंस्ट्रेंट वैल्यू भी हों. इसका यह भी मतलब है कि स्पेशलाइज़ेशन रिज़ॉल्यूशन को, क्रम बनाने के लिए डिज़ाइन नहीं किया गया है. जैसा कि यहां दिए गए दूसरे उदाहरण में दिखाया गया है.
- अगर एक से ज़्यादा शर्तें मेल खाती हैं और उनमें से कोई एक शर्त, अन्य सभी शर्तों की स्पेशलाइज़ेशन नहीं है, तो 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 फ़ाइल का डायरेक्ट डिसेंडेंट है. शामिल करने और बाहर रखने के पैटर्न के बारे में ज़्यादा जानकारी और उदाहरणों के लिए, glob देखें.इससे, सबपैकेज की जो सूची मिलती है वह क्रम से लगी होती है. इसमें, लोड किए जा रहे मौजूदा पैकेज के ऐसे पाथ होते हैं जो
include
में दिए गए पैटर्न से मेल खाते हैं, न किexclude
में दिए गए पैटर्न से.उदाहरण
यहां दिए गए उदाहरण में, पैकेज
foo/BUILD
के सभी डायरेक्ट सबपैकेज की सूची दी गई है# The following BUILD files exist: # foo/BUILD # foo/bar/baz/BUILD # foo/bar/but/bad/BUILD # foo/sub/BUILD # foo/sub/deeper/BUILD # # In foo/BUILD a call to subs1 = subpackages(include = ["**"]) # results in subs1 == ["sub", "bar/baz", "bar/but/bad"] # # 'sub/deeper' is not included because it is a subpackage of 'foo/sub' not of # 'foo' subs2 = subpackages(include = ["bar/*"]) # results in subs2 = ["bar/baz"] # # Since 'bar' is not a subpackage itself, this looks for any subpackages under # all first level subdirectories of 'bar'. subs3 = subpackages(include = ["bar/**"]) # results in subs3 = ["bar/baz", "bar/but/bad"] # # Since bar is not a subpackage itself, this looks for any subpackages which are # (1) under all subdirectories of 'bar' which can be at any level, (2) not a # subpackage of another subpackages. subs4 = subpackages(include = ["sub"]) subs5 = subpackages(include = ["sub/*"]) subs6 = subpackages(include = ["sub/**"]) # results in subs4 and subs6 being ["sub"] # results in subs5 = []. # # In subs4, expression "sub" checks whether 'foo/sub' is a package (i.e. is a # subpackage of 'foo'). # In subs5, "sub/*" looks for subpackages under directory 'foo/sub'. Since # 'foo/sub' is already a subpackage itself, the subdirectories will not be # traversed anymore. # In subs6, 'foo/sub' is a subpackage itself and matches pattern "sub/**", so it # is returned. But the subdirectories of 'foo/sub' will not be traversed # anymore.
आम तौर पर, इस फ़ंक्शन को सीधे तौर पर कॉल करने के बजाय, उपयोगकर्ताओं को skylib के 'subpackages' मॉड्यूल का इस्तेमाल करना चाहिए.