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