लेबल

लेबल किसी टारगेट का आइडेंटिफ़ायर होता है. कैननिकल फ़ॉर्म में, सामान्य लेबल ऐसा दिखता है:

@@myrepo//my/app/main:app_binary

लेबल का पहला हिस्सा, रिपॉज़िटरी का नाम @@myrepo होता है. डबल-@ सिंटैक्स से पता चलता है कि यह कैननिकल रिपो नेम है, जो वर्कस्पेस में यूनीक होता है. कैननिकल रिपो नेम वाले लेबल, टारगेट की साफ़ तौर पर पहचान करते हैं. भले ही, वे किसी भी कॉन्टेक्स्ट में दिखें.

अक्सर, कैननिकल रिपो नेम एक मुश्किल स्ट्रिंग होती है, जो @@rules_java++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 फ़ाइल वाली डायरेक्ट्री के मुकाबले, उसका पाथनेम होता है.

टारगेट के नाम में सिर्फ़ az, AZ, 09 वर्णों और विराम चिह्न !%-@^_"#$&'()*-+,;<=>?[]{|}~/. का इस्तेमाल किया जा सकता है.

फ़ाइलनेम, सामान्य फ़ॉर्म में रिलेटिव पाथनेम होने चाहिए. इसका मतलब है कि इनकी शुरुआत या खत्म स्लैश से नहीं होनी चाहिए. उदाहरण के लिए, /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.

तकनीकी तौर पर, Bazel इन चीज़ों को लागू करता है:

  • पैकेज के नामों में, अंग्रेज़ी के छोटे अक्षर 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 फ़ाइलें