लेबल, टारगेट के लिए आइडेंटिफ़ायर होता है. किसी सामान्य लेबल अपने पूरे कैननिकल फ़ॉर्म में ऐसा दिखता है:
@@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
जैसी स्ट्रिंग का मतलब, इस्तेमाल के कॉन्टेक्स्ट के हिसाब से दो तरह से होता है: जब Bazel को लेबल की ज़रूरत होती है, तो इनका मतलब क्रमशः //my/app:app
और @@some_repo//my/app:app
होता है. हालांकि, जब Basel को किसी पैकेज (जैसे कि 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 क्वेरी लैंग्वेज जैसे लेबल में बदलाव करने वाले टूल और स्क्रिप्ट को आसानी से बनाया जा सकता है.
टारगेट के लिए इस्तेमाल किए जा सकने वाले नामों के बारे में यहां पूरी जानकारी दी गई है.
टारगेट के नाम — 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
लेबल, //foo/bar/wiz:wiz
के लिए हमेशा एक शॉर्टहैंड होता है, भले ही ऐसा कोई पैकेज foo/bar/wiz
न हो. यह //foo:bar/wiz
का कभी भी ज़िक्र नहीं करता, भले ही टारगेट मौजूद हो.
हालांकि, कुछ मामलों में स्लैश का इस्तेमाल करना आसान होता है या कभी-कभी ज़रूरी भी होता है. उदाहरण के लिए, कुछ नियमों का नाम, उनकी मुख्य सोर्स फ़ाइल से मेल खाना चाहिए. यह फ़ाइल, पैकेज की सबडायरेक्ट्री में हो सकती है.
पैकेज के नाम — //package-name:target-name
पैकेज का नाम उस डायरेक्ट्री का नाम होता है जिसमें उसकी BUILD
फ़ाइल होती है. यह नाम, डेटा स्टोर करने की जगह की टॉप-लेवल डायरेक्ट्री के नाम होता है.
उदाहरण के लिए: my/app
.
पैकेज के नाम में सिर्फ़ 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
एट्रिब्यूट का टाइप "लेबल की सूची" होता है. अगर इसकी वैल्यू मौजूद है, तो यह लेबल की सूची होती है. हर लेबल, इस नियम के इनपुट के तौर पर काम करने वाले टारगेट का नाम होता है.
कुछ मामलों में, नियम का नाम कुछ हद तक अपने हिसाब से होता है और ज़्यादा दिलचस्प होता है कि नियम जनरेट होने वाली फ़ाइलों के नाम होते हैं और यह सामान्य नियमों की सही होती है. ज़्यादा जानकारी के लिए, सामान्य नियम: genrule देखें.
अन्य मामलों में, नाम का ज़्यादा महत्व होता है: उदाहरण के लिए, *_binary
और *_test
नियमों के लिए, नियम के नाम से यह तय होता है कि बिल्ड से तैयार किए गए, रन किए जा सकने वाले प्रोग्राम का नाम क्या होगा.
टारगेट पर डायरेक्ट किए गए एकसाइकल ग्राफ़ को टारगेट ग्राफ़ या बिल्ड डिपेंडेंसी ग्राफ़ कहा जाता है. यह वह डोमेन होता है जिस पर बेज़ल क्वेरी टूल काम करता है.
टारगेट | BUILD फ़ाइलें |