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