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

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

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

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

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

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

सामान्य BUILD फ़ाइलों में, नियमों का एलान करने वाले फ़ॉर्म का क्रम बदला जा सकता है.

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

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

BUILD फ़ाइलों को सिर्फ़ ASCII वर्णों का इस्तेमाल करके लिखा जाना चाहिए. हालांकि, तकनीकी तौर पर, इनका विश्लेषण Latin-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 नियम, दी गई प्रोग्रामिंग भाषा में अलग-अलग मॉड्यूल के बारे में बताते हैं. लाइब्रेरी, दूसरी लाइब्रेरी पर निर्भर हो सकती हैं. साथ ही, बाइनरी और टेस्ट, लाइब्रेरी पर निर्भर हो सकते हैं. हालांकि, इनके अलग-अलग कंपाइल होने की उम्मीद की जाती है.

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