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

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

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

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