फ़ाइल फ़ोल्डर, पैकेज, और टारगेट

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

Workspace

वर्कस्पेस , आपके फ़ाइल सिस्टम पर मौजूद डायरेक्ट्री ट्री होता है. इसमें, उस सॉफ़्टवेयर के सोर्स फ़ाइलें होती हैं जिसे आपको बनाना है. हर वर्कस्पेस में WORKSPACE नाम की एक टेक्स्ट फ़ाइल होती है. यह खाली हो सकती है या इसमें आउटपुट बनाने के लिए ज़रूरी बाहरी डिपेंडेंसी के रेफ़रंस हो सकते हैं.

WORKSPACE नाम की फ़ाइल वाली डायरेक्ट्री को, वर्कस्पेस का रूट माना जाता है. इसलिए, Bazel किसी वर्कस्पेस में मौजूद उन डायरेक्ट्री ट्री को अनदेखा करता है जिनका रूट, WORKSPACE फ़ाइल वाली सबडायरेक्ट्री होती है. ऐसा इसलिए, क्योंकि ये डायरेक्ट्री ट्री एक और वर्कस्पेस बनाते हैं.

Bazel, WORKSPACE फ़ाइल के एलियास के तौर पर WORKSPACE.bazel फ़ाइल को भी इस्तेमाल करने की सुविधा देता है. अगर दोनों फ़ाइलें मौजूद हैं, तो WORKSPACE.bazel का इस्तेमाल किया जाता है.

Repositories

कोड को रिपॉज़िटरी में व्यवस्थित किया जाता है. WORKSPACE फ़ाइल वाली डायरेक्ट्री, मुख्य रिपॉज़िटरी का रूट होती है. इसे @ भी कहा जाता है. अन्य (बाहरी) रिपॉज़िटरी को WORKSPACE फ़ाइल में, वर्कस्पेस के नियमों का इस्तेमाल करके तय किया जाता है. इसके अलावा, इन्हें Bzlmod सिस्टम में मौजूद मॉड्यूल और एक्सटेंशन से जनरेट किया जाता है. ज़्यादा जानकारी के लिए, बाहरी डिपेंडेंसी की खास जानकारी देखें.

Bazel के साथ बंडल किए गए वर्कस्पेस के नियमों के बारे में, Workspace Rules सेक्शन और Build Encyclopedia और embedded Starlark repository rules से जुड़े दस्तावेज़ में बताया गया है.

बाहरी रिपॉज़िटरी, खुद भी रिपॉज़िटरी होती हैं. इसलिए, इनमें अक्सर WORKSPACE फ़ाइल भी होती है. हालांकि, Bazel इन अतिरिक्त WORKSPACE फ़ाइलों को अनदेखा करता है. खास तौर पर, ट्रांज़िटिव तरीके से डिपेंडेंसी वाली रिपॉज़िटरी को अपने-आप नहीं जोड़ा जाता है.

Packages

किसी रिपॉज़िटरी में कोड को व्यवस्थित करने की मुख्य यूनिट, पैकेज होती है. पैकेज, एक-दूसरे से जुड़ी फ़ाइलों का कलेक्शन होता है. इसमें यह जानकारी होती है कि आउटपुट आर्टफ़ैक्ट बनाने के लिए, इन फ़ाइलों का इस्तेमाल कैसे किया जा सकता है.

किसी पैकेज को, 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

Targets

कोई पैकेज, टारगेट का कंटेनर होता है. टारगेट को पैकेज की BUILD फ़ाइल में तय किया जाता है. ज़्यादातर टारगेट, दो मुख्य तरह के होते हैं: फ़ाइलें और नियम.

फ़ाइलों को आगे दो तरह में बांटा जाता है. सोर्स फ़ाइलें आम तौर पर, लोगों की मेहनत से लिखी जाती हैं और इन्हें रिपॉज़िटरी में चेक इन किया जाता है. जनरेट की गई फ़ाइलें, जिन्हें कभी-कभी डिराइव की गई फ़ाइलें या आउटपुट फ़ाइलें भी कहा जाता है, चेक इन नहीं की जाती हैं. इन्हें सोर्स फ़ाइलों से जनरेट किया जाता है.

दूसरे तरह के टारगेट को नियम के साथ तय किया जाता है. नियम का हर इंस्टेंस, इनपुट और आउटपुट फ़ाइलों के सेट के बीच का संबंध तय करता है. किसी नियम के इनपुट, सोर्स फ़ाइलें हो सकती हैं. हालांकि, ये अन्य नियमों के आउटपुट भी हो सकते हैं.

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

किसी नियम के इनपुट में अन्य नियम भी शामिल हो सकते हैं. ऐसे संबंधों का सटीक मतलब अक्सर काफ़ी जटिल होता है. यह भाषा या नियम पर निर्भर करता है. हालांकि, यह सहज रूप से आसान है: C++ लाइब्रेरी के नियम A के लिए, C++ लाइब्रेरी का दूसरा नियम B इनपुट हो सकता है. इस डिपेंडेंसी का असर यह होता है कि कंपाइलेशन के दौरान, B की हेडर फ़ाइलें A के लिए उपलब्ध होती हैं. लिंकिंग के दौरान, B के सिंबल A के लिए उपलब्ध होते हैं. इसके अलावा, एक्ज़ीक्यूशन के दौरान, B का रनटाइम डेटा A के लिए उपलब्ध होता है.

सभी नियमों के लिए, यह ज़रूरी है कि किसी नियम से जनरेट की गई फ़ाइलें हमेशा उसी पैकेज से जुड़ी हों जिससे नियम जुड़ा है. किसी दूसरी पैकेज में फ़ाइलें जनरेट नहीं की जा सकतीं. हालांकि, ऐसा अक्सर होता है कि किसी नियम के इनपुट, किसी दूसरे पैकेज से आते हैं.

पैकेज ग्रुप, पैकेज के सेट होते हैं. इनका मकसद, कुछ नियमों के ऐक्सेस को सीमित करना होता है. पैकेज ग्रुप को package_group फ़ंक्शन से तय किया जाता है. इनकी तीन प्रॉपर्टी होती हैं: इनमें शामिल पैकेज की सूची, इनका नाम, और इनमें शामिल अन्य पैकेज ग्रुप. इन्हें सिर्फ़ नियमों के visibility एट्रिब्यूट या default_visibility फ़ंक्शन के package एट्रिब्यूट से रेफ़र किया जा सकता है. ये फ़ाइलें जनरेट या इस्तेमाल नहीं करते. ज़्यादा जानकारी के लिए, package_group दस्तावेज़ देखें.

लेबल