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

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

हर पैकेज में एक BUILD फ़ाइल होती है. यह एक छोटा प्रोग्राम होता है.

BUILD फ़ाइलों का आकलन, एक अनिवार्य भाषा, Starlark का इस्तेमाल करके किया जाता है.

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

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

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

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

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

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

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