लेबल

समस्या की शिकायत करें सोर्स देखें ठीक

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

@@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 जैसी स्ट्रिंग के दो मतलब होते हैं. यह इस बात पर निर्भर करता है कि उनका इस्तेमाल किस कॉन्टेक्स्ट में किया गया है: जब Baze किसी लेबल की उम्मीद करता है, तो उसका मतलब होता है //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 खोजता है. इसका इस्तेमाल खास तौर पर डेटा स्टोर करने की मुख्य जगह में ऐसे नियम लिखते समय किया जाता है जो डेटा स्टोर करने की मुख्य जगह में मौजूद टारगेट से जुड़े होते हैं. साथ ही, इसका इस्तेमाल एक्सटर्नल डेटा स्टोर करने की जगहों से किया जाएगा.

टारगेट को रेफ़र करने के अलग-अलग तरीकों के बारे में जानने के लिए, टारगेट पैटर्न देखें.

लेबल के बारे में लेक्सिकल जानकारी

लेबल सिंटैक्स ऐसे मेटावर्णों के इस्तेमाल को रोकने की कोशिश करता है जिनका शेल के लिए खास मतलब होता है. इससे अनजाने में होने वाली कोटेशन की समस्याओं से बचने में मदद मिलती है. साथ ही, लेबल में हेर-फेर करने वाले टूल और स्क्रिप्ट बनाने में भी आसानी होती है, जैसे कि Baaz क्वेरी लैंग्वेज.

टारगेट के लिए, सही नामों की जानकारी नीचे दी गई है.

टारगेट के नाम — 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.

तकनीकी स्तर पर, Basel ने इन चीज़ों को लागू किया है:

  • पैकेज के नामों में मौजूद अनुमति वाले वर्णों में ये शामिल हैं: a से z तक के छोटे अक्षर, A से Z तक के बड़े अक्षर, 0 से 9 तक के अंक, ! \"#$%&'()*+,-.;<=>?@[]^_`{|} (हां, इसमें एक स्पेस वर्ण है!), और आगे की ओर स्लैश / (क्योंकि यह डायरेक्ट्री सेपरेटर है).
  • पैकेज के नाम, फ़ॉरवर्ड स्लैश वर्ण / से शुरू या खत्म नहीं हो सकते.
  • पैकेज के नाम में // सबस्ट्रिंग नहीं हो सकती. इससे यह पता नहीं चलता कि इससे जुड़ा डायरेक्ट्री पाथ क्या होगा?
  • पैकेज के नामों में /./ या /../ या /.../ वगैरह शामिल नहीं हो सकता. नीति उल्लंघन ठीक करने के इस तरीके का इस्तेमाल, किसी लॉजिकल पैकेज के नाम और फ़िज़िकल डायरेक्ट्री के नाम के बीच अनुवाद करते समय, भ्रम की स्थिति से बचने के लिए किया जाता है. पाथ स्ट्रिंग में डॉट कैरेक्टर का सिमैंटिक मतलब दिया जाता है.

व्यावहारिक स्तर पर:

  • अगर डायरेक्ट्री स्ट्रक्चर वाली भाषा, उसके मॉड्यूल सिस्टम (जैसे, Java) के लिए अहम है, तो डायरेक्ट्री के ऐसे नाम चुनना ज़रूरी है जो उस भाषा में मान्य आइडेंटिफ़ायर हों. उदाहरण के लिए, किसी सबसे पहले अंक से शुरू न करें और विशेष वर्णों, खास तौर पर अंडरस्कोर और हाइफ़न का इस्तेमाल करने से बचें.
  • हालांकि, Workspace के रूट पैकेज (उदाहरण के लिए, //:foo) में टारगेट के साथ Basel का इस्तेमाल किया जाता है, लेकिन उस पैकेज को खाली छोड़ना ही बेहतर होता है, ताकि काम के सभी पैकेज के नाम में जानकारी मौजूद हो.

नियम

नियम, इनपुट और आउटपुट के बीच के संबंध की जानकारी देता है. साथ ही, आउटपुट बनाने के चरणों की जानकारी भी देता है. नियम कई तरह के हो सकते हैं. इन्हें कभी-कभी नियम क्लास भी कहा जाता है. ये नियम, कंपाइल किए गए एक्ज़ीक्यूटेबल और लाइब्रेरी, टेस्ट के एक्ज़ीक्यूटेबल, और काम करने वाले अन्य आउटपुट जनरेट करते हैं. इनके बारे में बिल्ड एनसाइक्लोपीडिया में बताया गया है.

BUILD फ़ाइलें, नियमों का इस्तेमाल करके टारगेट तय करती हैं.

नीचे दिए गए उदाहरण में, हमने cc_binary नियम का इस्तेमाल करके, टारगेट my_app का एलान किया है.

cc_binary(
    name = "my_app",
    srcs = ["my_app.cc"],
    deps = [
        "//absl/base",
        "//absl/strings",
    ],
)

हर नियम को शुरू करने के लिए एक name एट्रिब्यूट होता है, जो कि टारगेट का मान्य नाम होना चाहिए. यह एट्रिब्यूट, BUILD फ़ाइल के पैकेज में मौजूद किसी टारगेट की जानकारी देता है.

हर नियम में एट्रिब्यूट का एक सेट होता है. किसी नियम पर लागू होने वाले एट्रिब्यूट और हर एट्रिब्यूट का महत्व और सिमैंटिक, नियम के हिसाब से ही होते हैं. नियमों और उनसे जुड़े एट्रिब्यूट की सूची देखने के लिए, बिल्ड एनसाइक्लोपीडिया देखें. हर एट्रिब्यूट का एक नाम और टाइप होता है. किसी एट्रिब्यूट में आम तौर पर ये चीज़ें शामिल हो सकती हैं: पूर्णांक, लेबल, लेबल की सूची, स्ट्रिंग, स्ट्रिंग की सूची, आउटपुट लेबल, आउटपुट लेबल की सूची. हर नियम में सभी एट्रिब्यूट के बारे में बताना ज़रूरी नहीं है. इस तरह एट्रिब्यूट, बटन (नाम) से लेकर वैकल्पिक, टाइप की गई वैल्यू तक की डिक्शनरी तैयार करते हैं.

कई नियमों में मौजूद srcs एट्रिब्यूट का टाइप "लेबल की सूची" होता है. अगर इसकी वैल्यू मौजूद है, तो यह लेबल की एक सूची होती है. हर एक एट्रिब्यूट का नाम ऐसे टारगेट का नाम होता है जो इस नियम का इनपुट है.

कुछ मामलों में, नियम का नाम कुछ हद तक अपने हिसाब से होता है और सबसे दिलचस्प बात होती है कि नियम जनरेट होने वाली फ़ाइलों के नाम होते हैं और यह सामान्य नियमों की सही होती है. ज़्यादा जानकारी के लिए, सामान्य नियम: genन्या देखें.

अन्य मामलों में, यह नाम अहम होता है: *_binary और *_test नियमों के लिए, उदाहरण के लिए, नियम का नाम बिल्ड के ज़रिए बने एक्ज़ीक्यूटेबल का नाम तय करता है.

टारगेट पर डायरेक्ट किए गए एकसाइकल ग्राफ़ को टारगेट ग्राफ़ या बिल्ड डिपेंडेंसी ग्राफ़ कहा जाता है. यह वह डोमेन होता है जिस पर बेज़ल क्वेरी टूल काम करता है.

टारगेट फ़ाइलें बनाएं