Bazel, सोर्स कोड से सॉफ़्टवेयर बनाता है. सोर्स कोड को डायरेक्ट्री ट्री में व्यवस्थित किया जाता है. इसे वर्कस्पेस कहा जाता है. वर्कस्पेस में मौजूद सोर्स फ़ाइलों को, पैकेज के नेस्टेड क्रम में व्यवस्थित किया जाता है. हर पैकेज एक डायरेक्ट्री होती है, जिसमें सोर्स फ़ाइलों का सेट और एक BUILD फ़ाइल होती है. BUILD फ़ाइल में यह जानकारी होती है कि सोर्स से सॉफ़्टवेयर के कौनसे आउटपुट बनाए जा सकते हैं.
Workspace
वर्कस्पेस , आपके फ़ाइल सिस्टम पर मौजूद डायरेक्ट्री ट्री होता है. इसमें, उस सॉफ़्टवेयर के सोर्स फ़ाइलें होती हैं जिसे आपको बनाना है. हर वर्कस्पेस में
WORKSPACE नाम की एक टेक्स्ट फ़ाइल होती है. यह खाली हो सकती है या इसमें आउटपुट बनाने के लिए ज़रूरी बाहरी
डिपेंडेंसी के रेफ़रंस हो सकते हैं.
WORKSPACE नाम की फ़ाइल वाली डायरेक्ट्री को वर्कस्पेस का रूट माना जाता है. इसलिए, Bazel किसी वर्कस्पेस में मौजूद डायरेक्ट्री ट्री को अनदेखा करता है. ऐसा तब होता है, जब डायरेक्ट्री ट्री का रूट, WORKSPACE फ़ाइल वाली सबडायरेक्ट्री होती है. इसकी वजह यह है कि यह एक अलग वर्कस्पेस होता है.
Bazel, WORKSPACE फ़ाइल के एलियास के तौर पर WORKSPACE.bazel फ़ाइल को भी इस्तेमाल करने की अनुमति देता है. अगर दोनों फ़ाइलें मौजूद हैं, तो WORKSPACE.bazel का इस्तेमाल किया जाता है.
डेटा स्टोर करने की जगह
कोड को डेटा स्टोर करने की जगहों में व्यवस्थित किया जाता है. WORKSPACE फ़ाइल वाली डायरेक्ट्री, मुख्य डेटा स्टोर करने की जगह का रूट होती है. इसे @ भी कहा जाता है. अन्य (बाहरी) डेटा स्टोर करने की जगहों को WORKSPACE फ़ाइल में, वर्कस्पेस के नियमों का इस्तेमाल करके तय किया जाता है. इन्हें Bzlmod सिस्टम में मौजूद मॉड्यूल और एक्सटेंशन से जनरेट किया जाता है. ज़्यादा जानकारी के लिए, बाहरी
डिपेंडेंसी की खास जानकारी देखें.
Bazel के साथ बंडल किए गए वर्कस्पेस के नियमों के बारे में, Workspace Rules सेक्शन और Build Encyclopedia और embedded Starlark डेटा स्टोर करने की जगह के नियमों से जुड़े दस्तावेज़ में बताया गया है.
बाहरी डेटा स्टोर करने की जगहें, डेटा स्टोर करने की जगहें होती हैं. इसलिए, इनमें अक्सर WORKSPACE फ़ाइल भी होती है. हालांकि, Bazel इन अतिरिक्त WORKSPACE फ़ाइलों को अनदेखा करता है. खास तौर पर, ट्रांज़िटिव तरीके से डिपेंडेंसी वाली डेटा स्टोर करने की जगहों को अपने-आप नहीं जोड़ा जाता.
पैकेज
किसी डेटा स्टोर करने की जगह में, कोड को व्यवस्थित करने की मुख्य यूनिट पैकेज होती है. पैकेज, एक-दूसरे से जुड़ी फ़ाइलों का कलेक्शन होता है. इसमें यह जानकारी होती है कि आउटपुट आर्टफ़ैक्ट बनाने के लिए, इन फ़ाइलों का इस्तेमाल कैसे किया जा सकता है.
किसी पैकेज को,
BUILD फ़ाइल वाली डायरेक्ट्री के तौर पर तय किया जाता है. इसका नाम या तो 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 एट्रिब्यूट या default_visibility फ़ंक्शन के
package एट्रिब्यूट से रेफ़र किया जा सकता है. ये फ़ाइलें जनरेट या इस्तेमाल नहीं करते. ज़्यादा जानकारी के लिए, package_group
दस्तावेज़ देखें.