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