लेबल, टारगेट के लिए आइडेंटिफ़ायर होता है. अपने पूरे कैननिकल फ़ॉर्म में सामान्य लेबल, ऐसा दिखता है:
@@myrepo//my/app/main:app_binary
लेबल का पहला हिस्सा, डेटा स्टोर करने की जगह का नाम @@myrepo
होता है. डबल-@
सिंटैक्स से पता चलता है कि यह एक कैननिकल रेपो नाम है, जो वर्कस्पेस में यूनीक है. कैननिकल रेपो नामों वाले लेबल साफ़ तौर पर टारगेट की पहचान करते हैं,
इससे कोई फ़र्क़ नहीं पड़ता कि वे किस संदर्भ में हैं.
आम तौर पर, कैननिकल रेपो का नाम एक आर्केन स्ट्रिंग होता है जो
@@rules_java~7.1.0~toolchains~local_jdk
की तरह दिखता है. आम तौर पर ज़्यादा दिखने वाले लेबल में साफ़ तौर पर रेपो नाम मौजूद होता है, जो ऐसा दिखता है:
@myrepo//my/app/main:app_binary
फ़र्क़ सिर्फ़ इतना है कि रेपो के नाम की शुरुआत में दो के बजाय एक @
है.
यह साफ़ तौर पर दिखने वाले नाम myrepo
वाले रेपो की जानकारी देता है, जो इस लेबल के कॉन्टेक्स्ट के हिसाब से अलग हो सकता है.
आम तौर पर, अगर लेबल उसी डेटा स्टोर करने की जगह (डेटा स्टोर करने की जगह) से जुड़ा है जहां से इसका इस्तेमाल किया जाता है, तो हो सकता है कि रेपो के नाम वाले हिस्से को शामिल न किया जाए. इसलिए, @@myrepo
में पहला लेबल
आम तौर पर इस तरह लिखा जाता है
//my/app/main:app_binary
लेबल का दूसरा हिस्सा है, अमान्य पैकेज का नाम
my/app/main
, जो रिपॉज़िटरी रूट से जुड़े पैकेज का पाथ होता है. डेटा स्टोर करने की जगह का नाम और
अमान्य पैकेज का नाम, दोनों को मिलाकर पूरी तरह क्वालिफ़ाइड पैकेज नाम
@@myrepo//my/app/main
बनता है. अगर लेबल उसी पैकेज के बारे में बताता है जिसमें उसका इस्तेमाल किया गया है, तो पैकेज के नाम (और वैकल्पिक रूप से, कोलन) को शायद शामिल न किया जाए. इसलिए, @@myrepo//my/app/main
में यह लेबल इनमें से किसी एक तरीके से लिखा जा सकता है:
app_binary
:app_binary
यह सामान्य बात है कि फ़ाइलों के लिए कोलन का इस्तेमाल नहीं किया जाता, लेकिन नियमों के हिसाब से इसे बनाए रखा जाता है, लेकिन यह ज़रूरी नहीं है.
कोलन के बाद लेबल का हिस्सा, app_binary
ऐसा टारगेट नाम है जो ज़रूरी शर्तों को पूरा नहीं करता. जब यह पैकेज पाथ के आखिरी कॉम्पोनेंट से मेल खाता है, तो हो सकता है कि इसे और कोलन से हटा दिया जाए. इसलिए, ये दोनों लेबल एक जैसे हैं:
//my/app/lib
//my/app/lib:lib
पैकेज की सबडायरेक्ट्री में फ़ाइल टारगेट का नाम, पैकेज रूट (BUILD
फ़ाइल वाली डायरेक्ट्री) के हिसाब से फ़ाइल का पाथ होता है. इसलिए, यह फ़ाइल रिपॉज़िटरी की my/app/main/testdata
सबडायरेक्ट्री में है:
//my/app/main:testdata/input.txt
//my/app
और @@some_repo//my/app
जैसी स्ट्रिंग का इस्तेमाल किस संदर्भ में किया जाता है, इस आधार पर इनके दो मतलब होते हैं: जब बज़ल किसी लेबल की उम्मीद करता है, तब उनका मतलब //my/app:app
और @@some_repo//my/app:app
होता है. हालांकि, जब Bazel को किसी पैकेज (जैसे कि package_group
की खास बातों में) चाहिए, तब वह उस पैकेज के बारे में बताती है जिसमें वह लेबल होता है.
BUILD
फ़ाइलों में एक सामान्य गलती यह होती है कि पैकेज के बारे में बताने के लिए //my/app
का इस्तेमाल किया जाता है या पैकेज के सभी टारगेट के लिए इस्तेमाल किया जाता है. ऐसा नहीं होता. याद रखें कि यह
//my/app:app
के बराबर है. इसलिए, यह मौजूदा रिपॉज़िटरी के my/app
पैकेज में मौजूद app
टारगेट को नाम देता है.
हालांकि, package_group
या .bzl
फ़ाइलों की जानकारी में, पैकेज के बारे में बताने के लिए //my/app
के इस्तेमाल की सलाह दी जाती है. ऐसा इसलिए, क्योंकि इससे साफ़ तौर पर पता चलता है कि पैकेज का नाम पूरा है और फ़ाइल फ़ोल्डर की टॉप-लेवल डायरेक्ट्री में रूट किया गया है.
दूसरे पैकेज में मौजूद टारगेट को रेफ़र करने के लिए, रिलेटिव लेबल का इस्तेमाल नहीं किया जा सकता.
इस मामले में, डेटा स्टोर करने की जगह का आइडेंटिफ़ायर और पैकेज का नाम हमेशा बताना ज़रूरी है.
उदाहरण के लिए, अगर सोर्स ट्री में my/app
और पैकेज my/app/testdata
दोनों हैं (इन दोनों डायरेक्ट्री की अपनी BUILD
फ़ाइल है), तो बाद वाले पैकेज में testdepot.zip
नाम की फ़ाइल मौजूद होती है. इस फ़ाइल को //my/app:BUILD
में दिखाने के दो तरीके हैं (एक गलत, एक सही):
गलत — testdata
एक अलग पैकेज है, इसलिए किसी रिलेटिव पाथ का इस्तेमाल नहीं किया जा सकता
testdata/testdepot.zip
सही — testdata
के पूरे पाथ को देखें
//my/app/testdata:testdepot.zip
@@//
से शुरू होने वाले लेबल, डेटा स्टोर करने की मुख्य जगह के रेफ़रंस होते हैं. ये डेटा, बाहरी डेटा स्टोर करने की जगहों के साथ भी काम करेंगे.
इसलिए, बाहरी डेटा स्टोर करने की जगह से रेफ़र किए जाने पर, @@//a/b/c
, //a/b/c
से अलग होता है.
पहला रिपॉज़िटरी, मुख्य डेटा स्टोर करने की जगह के बारे में बताता है, जबकि पिछला वाला, बाहरी डेटा स्टोर करने की जगह में //a/b/c
को खोजता है.
यह खास तौर पर तब लागू होता है, जब डेटा स्टोर करने की मुख्य जगह में नियम लिखते हैं, जो मुख्य डेटा स्टोर करने की जगह के टारगेट से जुड़े होते हैं. इनका इस्तेमाल बाहरी डेटा स्टोर करने की जगहों से किया जाएगा.
टारगेट को रेफ़र करने के अलग-अलग तरीकों के बारे में जानने के लिए, टारगेट पैटर्न देखें.
किसी लेबल के बारे में खास जानकारी
लेबल सिंटैक्स ऐसे मेटाकैरेक्टर को इस्तेमाल करने से मना करता है जिनका शेल के लिए खास मतलब होता है. इससे अनजाने में कोट करने की समस्याओं से बचा जा सकता है. साथ ही, लेबल में हेर-फेर करने वाले टूल और स्क्रिप्ट को बनाना आसान हो जाता है, जैसे कि Bazel Query लैंग्वेज.
अनुमति वाले टारगेट के नामों की सटीक जानकारी नीचे दी गई है.
टारगेट के नाम — package-name:target-name
target-name
, पैकेज में मौजूद टारगेट का नाम है. नियम का नाम, BUILD
फ़ाइल के नियम के एलान में मौजूद name
एट्रिब्यूट की वैल्यू होता है. फ़ाइल का नाम, BUILD
फ़ाइल वाली डायरेक्ट्री के मुताबिक पाथनाम होता है.
टारगेट के नाम में, a
–z
,
A
–Z
, 0
–9
, और विराम चिह्न !%-@^_"#$&'()*-+,;<=>?[]{|}~/.
से लिए गए वर्ण शामिल होने चाहिए.
फ़ाइल नाम, सामान्य तौर पर दिए गए पाथनेम होने चाहिए. इसका मतलब है कि न तो उनकी शुरुआत में और न ही किसी स्लैश से खत्म होने चाहिए. उदाहरण के लिए, /foo
और foo/
इस्तेमाल करने की अनुमति नहीं है. साथ ही, पाथ सेपरेटर (जैसे, foo//bar
) के तौर पर, लगातार एक से ज़्यादा स्लैश इस्तेमाल नहीं किए जाने चाहिए. इसी तरह, अप-लेवल की पहचान फ़ाइलों (..
) और मौजूदा डायरेक्ट्री रेफ़रंस (./
) की अनुमति भी नहीं है.
गलत — अन्य पैकेज में मौजूद फ़ाइलों के बारे में बताने के लिए, ..
का इस्तेमाल न करें
सही — //package-name:filename
का इस्तेमाल करें
हालांकि, फ़ाइल टारगेट के नाम में /
का इस्तेमाल करना आम बात है, लेकिन नियमों के नामों में /
का इस्तेमाल करने से बचें. खास तौर पर जब किसी लेबल का शॉर्टहैंड फ़ॉर्म इस्तेमाल
किया गया हो, तो इससे पाठक भ्रम में पड़ सकता है. //foo/bar/wiz:wiz
के लिए, //foo/bar/wiz
लेबल हमेशा शॉर्टहैंड होता है. भले ही, ऐसा कोई पैकेज foo/bar/wiz
न हो; यह कभी भी //foo:bar/wiz
को रेफ़र नहीं करता, भले ही टारगेट मौजूद हो.
हालांकि, कुछ मामलों में स्लैश का इस्तेमाल करना आसान होता है या कभी-कभी ऐसा करना ज़रूरी भी होता है. उदाहरण के लिए, कुछ नियमों का नाम उनकी मुख्य सोर्स फ़ाइल से मेल खाना चाहिए, जो पैकेज की सबडायरेक्ट्री में मौजूद हो सकता है.
पैकेज के नाम — //package-name:target-name
पैकेज का नाम उस डायरेक्ट्री का नाम होता है जिसमें इसकी BUILD
फ़ाइल होती है. यह फ़ाइल, रिपॉज़िटरी की टॉप-लेवल की डायरेक्ट्री से मेल खाती है.
उदाहरण के लिए: my/app
.
तकनीकी स्तर पर, Bazel इन चीज़ों को लागू करता है:
- पैकेज के नामों में अनुमति वाले वर्ण हैं, अंग्रेज़ी के छोटे अक्षर,
a
सेz
तक,A
सेZ
तक के बड़े अक्षर,0
से9
तक के अंक,! \"#$%&'()*+,-.;<=>?@[]^_`{|}
वर्ण (हां, वहां एक स्पेस वर्ण है!), और फ़ॉरवर्ड स्लैश/
(यह डायरेक्ट्री सेपरेटर है). - पैकेज के नाम फ़ॉरवर्ड स्लैश वर्ण
/
से शुरू या खत्म नहीं हो सकते. - पैकेज के नाम में
//
सबस्ट्रिंग शामिल नहीं हो सकती. इससे कोई मतलब नहीं बनेगा---उसका डायरेक्ट्री पाथ क्या होगा? - पैकेज के नाम में सबस्ट्रिंग
/./
या/../
या/.../
वगैरह शामिल नहीं हो सकती. इसे लागू करने का मकसद, लॉजिकल पैकेज नाम और फ़िज़िकल डायरेक्ट्री के नाम के बीच अनुवाद करते समय भ्रम की स्थिति से बचना है. ऐसा पाथ स्ट्रिंग में मौजूद डॉट वर्ण के सिमैंटिक मतलब के आधार पर किया जाता है.
व्यावहारिक स्तर पर:
- डायरेक्ट्री स्ट्रक्चर वाली किसी ऐसी भाषा के लिए जो उसके मॉड्यूल सिस्टम (जैसे, Java) के लिए अहम है, ज़रूरी है कि डायरेक्ट्री के ऐसे नाम चुनें जो उस भाषा के मान्य आइडेंटिफ़ायर हों. उदाहरण के लिए, शुरुआत में किसी अंक से शुरू न करें. साथ ही, खास वर्णों, खास तौर पर अंडरस्कोर और हाइफ़न से बचें.
- हालांकि, Bazel, फ़ाइल फ़ोल्डर के रूट पैकेज (जैसे कि
//:foo
) में टारगेट के साथ काम करता है, लेकिन इस पैकेज को खाली रखना बेहतर होगा, ताकि काम के सभी पैकेज के नाम जानकारी देने वाले हों.
नियम
नियम, इनपुट और आउटपुट के बीच संबंध के बारे में बताता है. साथ ही, आउटपुट बनाने का तरीका भी बताता है. नियम कई अलग-अलग तरह के हो सकते हैं. इन्हें कभी-कभी नियम क्लास भी कहा जाता है. इनसे कंपाइल किए गए एक्ज़ीक्यूटेबल और लाइब्रेरी, टेस्ट एक्ज़ीक्यूटेबल, और बिल्ड एनसाइक्लोपीडिया में बताए गए अन्य आउटपुट जनरेट किए जा सकते हैं.
BUILD
फ़ाइलें, नियमों का इस्तेमाल करके टारगेट का एलान करती हैं.
इस उदाहरण में, हम cc_binary
नियम का इस्तेमाल करके, टारगेट my_app
का एलान देखते हैं.
cc_binary(
name = "my_app",
srcs = ["my_app.cc"],
deps = [
"//absl/base",
"//absl/strings",
],
)
शुरू किए जाने वाले हर नियम में एक name
एट्रिब्यूट होता है, जो एक मान्य टारगेट नाम होना चाहिए. इससे BUILD
फ़ाइल के पैकेज में मौजूद टारगेट के बारे में जानकारी मिलती है.
हर नियम में एट्रिब्यूट का एक सेट होता है. किसी नियम के लिए लागू एट्रिब्यूट, हर एट्रिब्यूट का महत्व और उसका मतलब, नियम के ही काम करता है. नियमों और उनसे जुड़े एट्रिब्यूट की सूची के लिए, एनसाइक्लोपीडिया बनाएं देखें. हर एट्रिब्यूट का एक नाम और टाइप होता है. कुछ सामान्य तरह के एट्रिब्यूट में ये शामिल हो सकते हैं: पूर्णांक, लेबल, लेबल की सूची, स्ट्रिंग, स्ट्रिंग की सूची, आउटपुट लेबल, और आउटपुट लेबल की सूची. हर नियम में सभी एट्रिब्यूट की जानकारी देना ज़रूरी नहीं है. इस तरह एट्रिब्यूट, बटन (नाम) से लेकर वैकल्पिक, टाइप की गई वैल्यू तक एक डिक्शनरी बनाते हैं.
कई नियमों में मौजूद srcs
एट्रिब्यूट में "लेबल की सूची" टाइप होता है. अगर वैल्यू मौजूद है, तो वह लेबल की सूची होती है. हर वैल्यू, टारगेट का नाम होती है जो इस नियम के लिए इनपुट के तौर पर इस्तेमाल होती है.
कुछ मामलों में, इस नियम का नाम कुछ हद तक आर्बिट्रेरी होता है. नियम से जनरेट की गई फ़ाइलों के नाम ज़्यादा दिलचस्प होते हैं. यह जेन नियमों के बारे में सही है. ज़्यादा जानकारी के लिए, सामान्य नियम: gen Rules देखें.
अन्य मामलों में, यह नाम अहम होता है: *_binary
और *_test
नियमों के लिए,
उदाहरण के लिए, नियम के नाम से बिल्ड से बनाए गए एक्ज़ीक्यूटेबल का नाम तय होता है.
टारगेट पर डायरेक्ट किए गए इस असाइकलिक ग्राफ़ को टारगेट ग्राफ़ या डिपेंडेंसी ग्राफ़ बनाएं कहा जाता है. यह वह डोमेन है जिस पर Bazel क्वेरी टूल काम करता है.
टारगेट | फ़ाइलें बनाएं |