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

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

परिभाषा के मुताबिक, हर पैकेज में एक 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_*. इनमें से कुछ फ़ंक्शन के बारे में Build Encyclopedia में बताया गया है. हालांकि, कोई भी व्यक्ति नए नियम बना सकता है.

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

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

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

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

  • *_library नियमों में, दी गई प्रोग्रामिंग भाषा में अलग-अलग कंपाइल किए गए मॉड्यूल के बारे में बताया जाता है. लाइब्रेरी, दूसरी लाइब्रेरी पर निर्भर हो सकती हैं. साथ ही, बाइनरी और टेस्ट, लाइब्रेरी पर निर्भर हो सकते हैं. हालांकि, इस दौरान अलग-अलग कंपाइल करने की सुविधा काम करती रहेगी.

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