Bazel, सोर्स कोड से सॉफ़्टवेयर बनाता है. सोर्स कोड को डायरेक्ट्री ट्री में व्यवस्थित किया जाता है. इसे वर्कस्पेस कहा जाता है. वर्कस्पेस में मौजूद सोर्स फ़ाइलें, पैकेज के नेस्ट किए गए पदानुक्रम में व्यवस्थित की जाती हैं. हर पैकेज एक डायरेक्ट्री होती है. इसमें मिलती-जुलती सोर्स फ़ाइलों का सेट और एक BUILD
फ़ाइल होती है. BUILD
फ़ाइल से यह पता चलता है कि सोर्स से कौनसे सॉफ़्टवेयर आउटपुट बनाए जा सकते हैं.
Workspace
वर्कस्पेस, आपके फ़ाइल सिस्टम पर एक डायरेक्ट्री ट्री होता है. इसमें उस सॉफ़्टवेयर के लिए सोर्स फ़ाइलें होती हैं जिसे आपको बनाना है. हर वर्कस्पेस में WORKSPACE
नाम की एक टेक्स्ट फ़ाइल होती है. यह खाली हो सकती है या इसमें आउटपुट बनाने के लिए ज़रूरी बाहरी डिपेंडेंसी के रेफ़रंस शामिल हो सकते हैं.
WORKSPACE
नाम की फ़ाइल वाली डायरेक्ट्री को Workspace का रूट माना जाता है. इसलिए, Bazel किसी भी डायरेक्ट्री ट्री को अनदेखा करता है. यह डायरेक्ट्री ट्री, किसी ऐसे फ़ाइल फ़ोल्डर में होता है जिसमें WORKSPACE
फ़ाइल होती है, क्योंकि ये डायरेक्ट्री ट्री एक और फ़ाइल फ़ोल्डर बनाते हैं.
Bazel, WORKSPACE
फ़ाइल के एलियास के तौर पर WORKSPACE.bazel
फ़ाइल का भी इस्तेमाल करता है.
अगर दोनों फ़ाइलें मौजूद हैं, तो WORKSPACE.bazel
का इस्तेमाल किया जाता है.
डेटा स्टोर करने की जगह
कोड को रिपॉज़िटरी में व्यवस्थित किया जाता है. WORKSPACE
फ़ाइल वाली डायरेक्ट्री, मुख्य रिपॉज़िटरी का रूट होती है. इसे @
भी कहा जाता है. अन्य (बाहरी) रिपॉज़िटरी को WORKSPACE
फ़ाइल में, Workspace के नियमों का इस्तेमाल करके तय किया जाता है.
Bazel के साथ बंडल किए गए वर्कस्पेस के नियमों के बारे में, Build Encyclopedia में वर्कस्पेस के नियम सेक्शन में बताया गया है. साथ ही, एम्बेड किए गए Starlark रिपॉज़िटरी के नियमों के बारे में भी बताया गया है.
बाहरी रिपॉज़िटरी, खुद एक रिपॉज़िटरी होती हैं. इसलिए, इनमें अक्सर WORKSPACE
फ़ाइल भी मौजूद होती है. हालांकि, Bazel इन अतिरिक्त WORKSPACE
फ़ाइलों को अनदेखा करता है. खास तौर पर, ट्रांज़िटिव डिपेंडेंसी वाली रिपॉज़िटरी अपने-आप नहीं जुड़ती हैं.
पैकेज
किसी रिपॉज़िटरी में कोड को व्यवस्थित करने की मुख्य इकाई पैकेज होती है. पैकेज, मिलती-जुलती फ़ाइलों का एक कलेक्शन होता है. इसमें यह जानकारी भी होती है कि आउटपुट आर्टफ़ैक्ट बनाने के लिए, इन फ़ाइलों का इस्तेमाल कैसे किया जा सकता है.
पैकेज को ऐसी डायरेक्ट्री के तौर पर तय किया जाता है जिसमें BUILD
(या BUILD.bazel
) नाम की फ़ाइल मौजूद हो. पैकेज में, उसकी डायरेक्ट्री में मौजूद सभी फ़ाइलें शामिल होती हैं. साथ ही, इसके नीचे मौजूद सभी सबडायरेक्ट्री भी शामिल होती हैं. हालांकि, इसमें वे सबडायरेक्ट्री शामिल नहीं होती हैं जिनमें BUILD
फ़ाइल मौजूद हो. इस परिभाषा के हिसाब से, कोई भी फ़ाइल या डायरेक्ट्री दो अलग-अलग पैकेज का हिस्सा नहीं हो सकती.
उदाहरण के लिए, यहां दिए गए डायरेक्ट्री ट्री में दो पैकेज हैं: my/app
और सबपैकेज my/app/tests
.
ध्यान दें कि my/app/data
कोई पैकेज नहीं है, बल्कि पैकेज my/app
से जुड़ी एक डायरेक्ट्री है.
src/my/app/BUILD
src/my/app/app.cc
src/my/app/data/input.txt
src/my/app/tests/BUILD
src/my/app/tests/test.cc
टारगेट
पैकेज, टारगेट का कंटेनर होता है. इन्हें पैकेज की BUILD
फ़ाइल में तय किया जाता है. ज़्यादातर टारगेट, दो मुख्य तरह के होते हैं: फ़ाइलें और नियम.
फ़ाइलों को दो कैटगरी में बांटा गया है. सोर्स फ़ाइलें आम तौर पर, लोगों के प्रयासों से लिखी जाती हैं और इन्हें रिपॉज़िटरी में सेव किया जाता है. जनरेट की गई फ़ाइलों को कभी-कभी डिराइव की गई फ़ाइलें या आउटपुट फ़ाइलें भी कहा जाता है. इन्हें चेक इन नहीं किया जाता, बल्कि सोर्स फ़ाइलों से जनरेट किया जाता है.
दूसरे तरह के टारगेट की जानकारी, नियम के ज़रिए दी जाती है. हर नियम के इंस्टेंस में, इनपुट फ़ाइलों के सेट और आउटपुट फ़ाइलों के सेट के बीच का संबंध बताया जाता है. किसी नियम के इनपुट, सोर्स फ़ाइलें हो सकती हैं. हालांकि, वे अन्य नियमों के आउटपुट भी हो सकती हैं.
किसी नियम के लिए इनपुट, सोर्स फ़ाइल है या जनरेट की गई फ़ाइल, इससे ज़्यादातर मामलों में कोई फ़र्क़ नहीं पड़ता. सिर्फ़ उस फ़ाइल का कॉन्टेंट मायने रखता है. इस वजह से, किसी जटिल सोर्स फ़ाइल को नियम के हिसाब से जनरेट की गई फ़ाइल से बदलना आसान हो जाता है. ऐसा तब होता है, जब किसी स्ट्रक्चर्ड फ़ाइल को मैन्युअल तरीके से बनाए रखना बहुत मुश्किल हो जाता है और कोई व्यक्ति उसे बनाने के लिए प्रोग्राम लिखता है. उस फ़ाइल का इस्तेमाल करने वाले लोगों को कोई बदलाव करने की ज़रूरत नहीं है. इसके उलट, जनरेट की गई फ़ाइल को, सिर्फ़ लोकल बदलावों वाली सोर्स फ़ाइल से आसानी से बदला जा सकता है.
किसी नियम के इनपुट में, दूसरे नियम भी शामिल हो सकते हैं. इस तरह के संबंधों का सटीक मतलब अक्सर काफ़ी जटिल होता है. साथ ही, यह भाषा या नियम पर निर्भर करता है. हालांकि, यह समझना आसान है: C++ लाइब्रेरी के नियम A के लिए, C++ लाइब्रेरी का दूसरा नियम B इनपुट हो सकता है. इस डिपेंडेंसी का असर यह होता है कि B की हेडर फ़ाइलें, कंपाइलेशन के दौरान A के लिए उपलब्ध होती हैं. साथ ही, B के सिंबल, लिंकिंग के दौरान A के लिए उपलब्ध होते हैं. इसके अलावा, B का रनटाइम डेटा, एक्ज़ीक्यूशन के दौरान A के लिए उपलब्ध होता है.
सभी नियमों के लिए यह ज़रूरी है कि किसी नियम से जनरेट की गई फ़ाइलें, हमेशा उसी पैकेज से जुड़ी हों जिससे नियम जुड़ा है. किसी दूसरे पैकेज में फ़ाइलें जनरेट नहीं की जा सकतीं. हालांकि, ऐसा अक्सर होता है कि किसी नियम के इनपुट, किसी दूसरे पैकेज से आते हैं.
पैकेज ग्रुप, पैकेज के ऐसे सेट होते हैं जिनका मकसद कुछ नियमों के ऐक्सेस को सीमित करना होता है. पैकेज ग्रुप, package_group
फ़ंक्शन के हिसाब से तय किए जाते हैं.
इनमें तीन प्रॉपर्टी होती हैं: इनमें शामिल पैकेज की सूची, इनका नाम, और इनमें शामिल अन्य पैकेज ग्रुप. इन्हें सिर्फ़ इन तरीकों से रेफ़र किया जा सकता है:
नियमों के visibility
एट्रिब्यूट से या package
फ़ंक्शन के default_visibility
एट्रिब्यूट से. ये फ़ाइलें जनरेट या इस्तेमाल नहीं करते.
ज़्यादा जानकारी के लिए, package_group
दस्तावेज़ पढ़ें.