फ़ाइलें बनाएं

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

परिभाषा के मुताबिक, हर पैकेज में एक BUILD फ़ाइल होती है, जो एक छोटा प्रोग्राम होता है. BUILD फ़ाइलों का आकलन ज़रूरी भाषा, Starlark का इस्तेमाल करके किया जाता है.

उन्हें स्टेटमेंट की क्रम वाली सूची के तौर पर समझा जाता है.

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

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

आसान BUILD फ़ाइलों में, नियम की सूचनाओं का क्रम बिना किसी बदलाव के बदला जा सकता है.

कोड और डेटा को साफ़ तौर पर अलग-अलग करने के लिए, BUILD फ़ाइलों में फ़ंक्शन परिभाषाएं, for स्टेटमेंट या if स्टेटमेंट नहीं हो सकते (लेकिन समझ और if एक्सप्रेशन की अनुमति है). इसके बजाय, फ़ंक्शन .bzl फ़ाइलों में बनाए जा सकते हैं. इसके अलावा, BUILD फ़ाइलों में *args और **kwargs आर्ग्युमेंट की अनुमति नहीं है. इसके बजाय, सभी तर्कों को साफ़ तौर पर बताएं.

खास तौर पर, Starlark में प्रोग्राम मनचाहे तरीके से I/O नहीं कर सकते. यह इन्वेरिएंट BUILD फ़ाइलों को हेर्मेटिक बनाता है. यह सिर्फ़ इनपुट के पहले से मौजूद सेट पर निर्भर करता है. इससे यह पक्का किया जा सकता है कि बिल्ड फिर से जनरेट किए जा सकते हैं. ज़्यादा जानकारी के लिए, Hermeticity देखें.

BUILD फ़ाइलों में सिर्फ़ ASCII वर्णों का इस्तेमाल करके लिखा जाना चाहिए. हालांकि, तकनीकी रूप से उनकी व्याख्या लैटिन-1 वर्ण सेट का इस्तेमाल करके की जानी चाहिए.

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

एक्सटेंशन लोड किया जा रहा है

Bazel एक्सटेंशन, .bzl से खत्म होने वाली फ़ाइलें हैं. किसी एक्सटेंशन से सिंबल इंपोर्ट करने के लिए, load स्टेटमेंट का इस्तेमाल करें.

load("//foo/bar:file.bzl", "some_library")

यह कोड foo/bar/file.bzl फ़ाइल को लोड करता है और some_library सिंबल को एनवायरमेंट में जोड़ देता है. इसका इस्तेमाल नए नियमों, फ़ंक्शन या कॉन्सटेंट (उदाहरण के लिए, कोई स्ट्रिंग या सूची) को लोड करने के लिए किया जा सकता है. load को किए गए कॉल में दूसरे तर्कों का इस्तेमाल करके, एक से ज़्यादा सिंबल इंपोर्ट किए जा सकते हैं. तर्क, स्ट्रिंग लिटरल होने चाहिए (कोई वैरिएबल नहीं) और load स्टेटमेंट टॉप लेवल पर होने चाहिए — वे फ़ंक्शन के मुख्य हिस्से में नहीं हो सकते.

load का पहला आर्ग्युमेंट, .bzl फ़ाइल की पहचान करने वाला लेबल होता है. अगर यह कोई मिलता-जुलता लेबल है, तो इसे मौजूदा bzl फ़ाइल वाले पैकेज (डायरेक्ट्री के बजाय) के हिसाब से रिज़ॉल्व किया जाता है. load स्टेटमेंट में मौजूद मिलते-जुलते लेबल में, सबसे पहले : का इस्तेमाल होना चाहिए.

load, उपनामों का भी इस्तेमाल करता है. इसलिए, इंपोर्ट किए गए सिंबल को अलग-अलग नाम असाइन किए जा सकते हैं.

load("//foo/bar:file.bzl", library_alias = "some_library")

आप एक load स्टेटमेंट में एक से ज़्यादा उपनाम तय कर सकते हैं. इसके अलावा, तर्क सूची में उपनाम और सामान्य चिह्न वाले नाम, दोनों शामिल हो सकते हैं. यह उदाहरण पूरी तरह से कानूनी है (कृपया ध्यान दें कि कोटेशन मार्क का इस्तेमाल कब करना है).

load(":my_rules.bzl", "some_rule", nice_alias = "some_other_rule")

.bzl फ़ाइल में, _ से शुरू होने वाले सिंबल एक्सपोर्ट नहीं किए जाते और उन्हें किसी दूसरी फ़ाइल से लोड नहीं किया जा सकता.

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

बिल्ड के नियम किस तरह के हैं

बिल्ड के ज़्यादातर नियम फ़ैमिली में आते हैं. इन्हें भाषा के हिसाब से ग्रुप में बांटा जाता है. उदाहरण के लिए, cc_binary, cc_library, और cc_test C++ बाइनरी, लाइब्रेरी, और टेस्ट के लिए बिल्ड रूल होते हैं. अन्य भाषाओं में इसी नाम देने की स्कीम का इस्तेमाल होता है, जिसमें अलग-अलग प्रीफ़िक्स हैं, जैसे कि Java के लिए java_*. इनमें से कुछ फ़ंक्शन बिल्ड इनसाइक्लोपीडिया में बताए गए हैं. हालांकि, कोई भी व्यक्ति नए नियम बना सकता है.

  • *_binary नियम, किसी दी गई भाषा में एक्ज़ीक्यूटेबल प्रोग्राम बनाते हैं. बिल्ड होने के बाद, एक्ज़ीक्यूटेबल, बिल्ड टूल के बाइनरी आउटपुट ट्री में नियम के लेबल के संबंधित नाम पर मौजूद होगा, इसलिए //my:program (उदाहरण के लिए) $(BINDIR)/my/program पर दिखेगा.

    कुछ भाषाओं में, इस तरह के नियम एक रनफ़ाइल डायरेक्ट्री भी बनाते हैं. इसमें, data एट्रिब्यूट में बताई गई सभी फ़ाइलें शामिल होती हैं. यह डायरेक्ट्री, डिपेंडेंसी के दौरान किसी नियम या इस नियम के अस्थायी तौर पर बंद होने से जुड़ी होती है. प्रोडक्शन में आसानी के लिए इन फ़ाइलों का सेट एक ही जगह पर इकट्ठा किया जाता है.

  • *_test नियम, *_binary नियम की विशेषज्ञता है. इसका इस्तेमाल अपने-आप होने वाली जांच के लिए किया जाता है. टेस्ट ऐसे प्रोग्राम होते हैं जो सफल होने पर शून्य दिखाते हैं.

    बाइनरी की तरह, टेस्ट में भी रनफ़ाइल ट्री होते हैं और इसके नीचे मौजूद फ़ाइलें ही ऐसी फ़ाइलें होती हैं जिन्हें टेस्ट, रनटाइम के दौरान सही तरीके से खोल सकता है. उदाहरण के लिए, प्रोग्राम चलने के दौरान cc_test(name='x', data=['//foo:bar']), $TEST_SRCDIR/workspace/foo/bar को खोलकर पढ़ सकता है. ($TEST_SRCDIR की वैल्यू को ऐक्सेस करने के लिए, हर प्रोग्रामिंग भाषा का अपना यूटिलिटी फ़ंक्शन होता है. हालांकि, ये सभी एनवायरमेंट वैरिएबल का सीधे तौर पर इस्तेमाल करने के बराबर होता है.) नियम का पालन न करने पर, रिमोट टेस्टिंग होस्ट पर लागू किए जाने पर टेस्ट फ़ेल हो जाएगा.

  • *_library नियम, प्रोग्रामिंग भाषा में अलग से इकट्ठा किए गए मॉड्यूल दिखाते हैं. लाइब्रेरी, दूसरी लाइब्रेरी पर निर्भर हो सकती हैं. साथ ही, बाइनरी और टेस्ट, लाइब्रेरी पर निर्भर हो सकते हैं. इसके लिए ज़रूरी है कि उन्हें अलग-अलग कंपाइलेशन में रखा गया हो.

लेबल डिपेंडेंसी