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

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

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

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

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

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

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

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

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

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

जब भी कोड की डिपेंडेंसी में बदलाव होता है, तब 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 फ़ाइल को लोड करने की अनुमति किसे है.

बिल्ड नियमों के टाइप

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

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

फ़ाइल एन्कोडिंग

BUILD और .bzl फ़ाइलों को UTF-8 में एन्कोड किया जाना चाहिए. ASCII, इसका मान्य सबसेट है. फ़िलहाल, बाइट के किसी भी क्रम का इस्तेमाल किया जा सकता है. हालांकि, आने वाले समय में यह सुविधा बंद की जा सकती है.