लेबल किसी टारगेट का आइडेंटिफ़ायर होता है. कैननिकल फ़ॉर्म में, सामान्य लेबल ऐसा दिखता है:
@@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 होता है. हालांकि, जब 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 Language जैसे लेबल में बदलाव करने वाले टूल और स्क्रिप्ट बनाना आसान हो जाता है.
यहां, टारगेट के मान्य नामों के बारे में पूरी जानकारी दी गई है.
टारगेट के नाम — 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 Encyclopedia में बताया गया है.
BUILD फ़ाइलें, नियमों को लागू करके टारगेट का एलान करती हैं.
यहां दिए गए उदाहरण में, cc_binary नियम का इस्तेमाल करके, my_app टारगेट के एलान को दिखाया गया है.
cc_binary(
name = "my_app",
srcs = ["my_app.cc"],
deps = [
"//absl/base",
"//absl/strings",
],
)
नियम के हर लागू करने में, name एट्रिब्यूट होता है. यह एट्रिब्यूट, BUILD फ़ाइल के पैकेज में किसी टारगेट का एलान करता है. साथ ही, यह मान्य
टारगेट नाम होना चाहिए.
हर नियम में एट्रिब्यूट का एक सेट होता है. किसी नियम के लिए लागू होने वाले एट्रिब्यूट, हर एट्रिब्यूट का मतलब, और सिमैंटिक्स, नियम के टाइप पर निर्भर करते हैं. नियमों और उनसे जुड़े एट्रिब्यूट की सूची के लिए, Build Encyclopedia देखें. हर एट्रिब्यूट का एक नाम और एक टाइप होता है. किसी एट्रिब्यूट के कुछ सामान्य टाइप, इंटीजर, लेबल, लेबल की सूची, स्ट्रिंग, स्ट्रिंग की सूची, आउटपुट लेबल, आउटपुट लेबल की सूची हैं. यह ज़रूरी नहीं है कि हर नियम में सभी एट्रिब्यूट की जानकारी दी जाए. इस तरह, एट्रिब्यूट, कुंजियों (नाम) से लेकर वैकल्पिक, टाइप की गई वैल्यू तक की एक डिक्शनरी बनाते हैं.
कई नियमों में मौजूद srcs एट्रिब्यूट का टाइप "लेबल की सूची" होता है. अगर इसकी वैल्यू मौजूद है, तो यह लेबल की एक सूची होती है. इनमें से हर लेबल, किसी ऐसे टारगेट का नाम होता है जो इस नियम के लिए इनपुट है.
कुछ मामलों में, नियम के टाइप का नाम कुछ हद तक मनमाना होता है. साथ ही, नियम से जनरेट होने वाली फ़ाइलों के नाम ज़्यादा दिलचस्प होते हैं. यह बात, genrules पर भी लागू होती है. ज़्यादा जानकारी के लिए, सामान्य नियम: genrule देखें.
अन्य मामलों में, नाम अहम होता है. उदाहरण के लिए, *_binary और *_test नियमों के लिए, नियम का नाम, बिल्ड से जनरेट होने वाले एक्ज़ीक्यूटेबल का नाम तय करता है.
टारगेट पर बने इस डायरेक्टेड एसाइक्लिक ग्राफ़ को टारगेट ग्राफ़ या बिल्ड डिपेंडेंसी ग्राफ़ कहा जाता है. यह वह डोमेन है जिस पर Bazel Query टूल काम करता है.
| टारगेट | BUILD फ़ाइलें |