परिचय
क्या आपने पहले कभी Bazel का इस्तेमाल नहीं किया है? आप बिलकुल सही जगह पर हैं. Bazel का इस्तेमाल करने के बारे में आसान तरीके से जानने के लिए, इस पहले बिल्ड ट्यूटोरियल को देखें. इस ट्यूटोरियल में, Bazel के कॉन्टेक्स्ट में इस्तेमाल किए गए मुख्य शब्दों की परिभाषाएं दी गई हैं. साथ ही, इसमें Bazel के वर्कफ़्लो के बारे में बुनियादी जानकारी दी गई है. आपको अपनी ज़रूरत के हिसाब से टूल इस्तेमाल करने का मौका मिलेगा. साथ ही, आपको तीन प्रोजेक्ट बनाने और उन्हें चलाने का मौका मिलेगा. इन प्रोजेक्ट में, मुश्किलों का लेवल बढ़ता जाएगा. आपको यह भी पता चलेगा कि ये प्रोजेक्ट कैसे और क्यों ज़्यादा मुश्किल होते जाते हैं.
Bazel एक बिल्ड सिस्टम है, जो कई भाषाओं में बिल्ड करने की सुविधा देता है. हालांकि, इस ट्यूटोरियल में C++ प्रोजेक्ट का इस्तेमाल किया गया है. साथ ही, इसमें सामान्य दिशा-निर्देश और फ़्लो दिए गए हैं, जो ज़्यादातर भाषाओं पर लागू होते हैं.
पूरा होने में लगने वाला अनुमानित समय: 30 मिनट.
ज़रूरी शर्तें
अगर आपने पहले से Bazel इंस्टॉल नहीं किया है, तो सबसे पहले इसे इंस्टॉल करें. इस ट्यूटोरियल में, सोर्स कंट्रोल के लिए Git का इस्तेमाल किया गया है. इसलिए, बेहतर नतीजों के लिए Git इंस्टॉल करें.
इसके बाद, Bazel की GitHub रिपॉज़िटरी से सैंपल प्रोजेक्ट पाएं. इसके लिए, अपनी पसंद की कमांड-लाइन टूल में यह कमांड चलाएं:
git clone https://github.com/bazelbuild/examplesइस ट्यूटोरियल के लिए सैंपल प्रोजेक्ट, examples/cpp-tutorial
डायरेक्ट्री में है.
देखें कि इसे कैसे बनाया गया है:
examples
└── cpp-tutorial
├──stage1
│ ├── main
│ │ ├── BUILD
│ │ └── hello-world.cc
│ └── MODULE.bazel
├──stage2
│ ├── main
│ │ ├── BUILD
│ │ ├── hello-world.cc
│ │ ├── hello-greet.cc
│ │ └── hello-greet.h
│ └── MODULE.bazel
└──stage3
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
│ └── hello-time.h
└── MODULE.bazel
फ़ाइलों के तीन सेट हैं. हर सेट, इस ट्यूटोरियल के एक चरण को दिखाता है. पहले चरण में, आपको एक पैकेज में मौजूद एक टारगेट बनाना होगा. दूसरे चरण में, आपको एक ही पैकेज से बाइनरी और लाइब्रेरी, दोनों बनानी होंगी. तीसरे और आखिरी चरण में, आपको कई पैकेज वाला प्रोजेक्ट बनाना होगा. साथ ही, इसे कई टारगेट के साथ बनाना होगा.
खास जानकारी: शुरुआती जानकारी
Bazel और Git को इंस्टॉल करके और इस ट्यूटोरियल के लिए रिपॉज़िटरी को क्लोन करके, आपने Bazel के साथ अपनी पहली बिल्ड के लिए बुनियादी ढांचा तैयार कर लिया है. कुछ शब्दों को तय करने और अपना वर्कस्पेस सेट अप करने के लिए, अगले सेक्शन पर जाएं.
शुरू करना
कोई प्रोजेक्ट बनाने से पहले, आपको उसका वर्कस्पेस सेट अप करना होगा. वर्कस्पेस एक डायरेक्ट्री होती है. इसमें आपके प्रोजेक्ट की सोर्स फ़ाइलें और Bazel के बिल्ड आउटपुट होते हैं. इसमें ये अहम फ़ाइलें भी शामिल हैं:
MODULE.bazelफ़ाइल, डायरेक्ट्री और उसके कॉन्टेंट की पहचान Bazel वर्कस्पेस के तौर पर करती है. यह प्रोजेक्ट की डायरेक्ट्री स्ट्रक्चर के रूट में मौजूद होती है. इसी फ़ाइल में, बाहरी डिपेंडेंसी के बारे में भी बताया जाता है.- एक या इससे ज़्यादा
BUILDफ़ाइलें. इनसे Bazel को यह पता चलता है कि प्रोजेक्ट के अलग-अलग हिस्सों को कैसे बनाया जाए. वर्कस्पेस में मौजूद ऐसी डायरेक्ट्री जिसमेंBUILDफ़ाइल होती है उसे पैकेज कहा जाता है. (इस ट्यूटोरियल में पैकेज के बारे में बाद में ज़्यादा जानकारी दी गई है.)
आने वाले समय में, किसी डायरेक्ट्री को Bazel वर्कस्पेस के तौर पर सेट करने के लिए, उस डायरेक्ट्री में MODULE.bazel नाम की एक खाली फ़ाइल बनाएं. इस ट्यूटोरियल के लिए, हर स्टेज में MODULE.bazel फ़ाइल पहले से मौजूद है.
BUILD फ़ाइल के बारे में जानकारी
BUILD फ़ाइल में, Bazel के लिए कई तरह के निर्देश होते हैं. हर BUILD फ़ाइल में कम से कम एक नियम होना चाहिए. यह निर्देशों का एक सेट होता है. इससे Bazel को यह पता चलता है कि आपको कौनसे आउटपुट बनाने हैं. जैसे, एक्ज़ीक्यूटेबल बाइनरी या लाइब्रेरी. BUILD फ़ाइल में मौजूद बिल्ड रूल के हर इंस्टेंस को टारगेट कहा जाता है. यह सोर्स फ़ाइलों और डिपेंडेंसी के किसी खास सेट की ओर इशारा करता है. कोई टारगेट, दूसरे टारगेट की ओर भी पॉइंट कर सकता है.
cpp-tutorial/stage1/main डायरेक्ट्री में मौजूद BUILD फ़ाइल देखें:
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
)
हमारे उदाहरण में, hello-world टारगेट, Bazel के बिल्ट-इन cc_binary नियम को इंस्टैंटिएट करता है. इस नियम से Bazel को यह निर्देश मिलता है कि वह hello-world.cc> सोर्स फ़ाइल से, बिना किसी डिपेंडेंसी के एक एक्ज़ीक्यूटेबल बाइनरी बनाए.
खास जानकारी: शुरू करना
अब आपको कुछ मुख्य शब्दों के बारे में पता चल गया है. साथ ही, आपको यह भी पता चल गया है कि इस प्रोजेक्ट और Bazel के संदर्भ में उनका क्या मतलब है. अगले सेक्शन में, प्रोजेक्ट के पहले चरण को बनाया और टेस्ट किया जाएगा.
पहला चरण: एक टारगेट, एक पैकेज
अब प्रोजेक्ट का पहला हिस्सा बनाने का समय है. विज़ुअल रेफ़रंस के लिए, प्रोजेक्ट के पहले चरण के सेक्शन का स्ट्रक्चर यह है:
examples
└── cpp-tutorial
└──stage1
├── main
│ ├── BUILD
│ └── hello-world.cc
└── MODULE.bazel
cpp-tutorial/stage1 डायरेक्ट्री पर जाने के लिए, यह कमांड चलाएं:
cd cpp-tutorial/stage1इसके बाद, यह कमांड चलाएं:
bazel build //main:hello-worldटारगेट लेबल में, //main: हिस्सा, Workspace के रूट के हिसाब से BUILD फ़ाइल की जगह की जानकारी देता है. वहीं, hello-world, BUILD फ़ाइल में टारगेट का नाम होता है.
Bazel, इस तरह का कुछ आउटपुट जनरेट करता है:
INFO: Found 1 target...
Target //main:hello-world up-to-date:
bazel-bin/main/hello-world
INFO: Elapsed time: 2.267s, Critical Path: 0.25s
आपने अभी-अभी अपना पहला Bazel टारगेट बनाया है. Bazel, बिल्ड आउटपुट को वर्कस्पेस के रूट में मौजूद bazel-bin डायरेक्ट्री में रखता है.
अब अपने नए बाइनरी की जांच करें. यह बाइनरी:
bazel-bin/main/hello-worldइस वजह से, प्रिंट किए गए पेज पर "Hello world" मैसेज दिखता है.
यहां स्टेज 1 का डिपेंडेंसी ग्राफ़ दिया गया है:

खास जानकारी: पहला चरण
अब आपने पहला बिल्ड पूरा कर लिया है. इससे आपको बिल्ड के स्ट्रक्चर के बारे में बुनियादी जानकारी मिल गई है. अगले चरण में, एक और टारगेट जोड़कर इसे और मुश्किल बनाया जाएगा.
दूसरा चरण: एक से ज़्यादा बिल्ड टारगेट
छोटे प्रोजेक्ट के लिए, एक टारगेट काफ़ी होता है. हालांकि, बड़े प्रोजेक्ट को कई टारगेट और पैकेज में बांटा जा सकता है. इससे तेज़ी से इंक्रीमेंटल बिल्ड तैयार किए जा सकते हैं. इसका मतलब है कि Bazel सिर्फ़ उन हिस्सों को फिर से बनाता है जिनमें बदलाव किया गया है. साथ ही, यह एक साथ किसी प्रोजेक्ट के कई हिस्सों को बनाकर, आपके बिल्ड को तेज़ करता है. ट्यूटोरियल के इस चरण में एक टारगेट जोड़ा जाता है. इसके बाद, अगले चरण में एक पैकेज जोड़ा जाता है.
यह वह डायरेक्ट्री है जिसका इस्तेमाल आपको दूसरे चरण में करना है:
├──stage2
│ ├── main
│ │ ├── BUILD
│ │ ├── hello-world.cc
│ │ ├── hello-greet.cc
│ │ └── hello-greet.h
│ └── MODULE.bazel
cpp-tutorial/stage2/main डायरेक्ट्री में मौजूद BUILD फ़ाइल देखें:
cc_library(
name = "hello-greet",
srcs = ["hello-greet.cc"],
hdrs = ["hello-greet.h"],
)
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
deps = [
":hello-greet",
],
)
इस BUILD फ़ाइल की मदद से, Bazel सबसे पहले hello-greet लाइब्रेरी बनाता है. इसके लिए, Bazel के बिल्ट-इन cc_library
नियम का इस्तेमाल किया जाता है. इसके बाद, hello-world बाइनरी बनाई जाती है. hello-world टारगेट में मौजूद deps एट्रिब्यूट, Bazel को बताता है कि hello-world बाइनरी बनाने के लिए hello-greet लाइब्रेरी की ज़रूरत है.
प्रोजेक्ट का यह नया वर्शन बनाने से पहले, आपको डायरेक्ट्री बदलनी होगी. इसके लिए, यह कमांड चलाकर cpp-tutorial/stage2 डायरेक्ट्री पर स्विच करें:
cd ../stage2अब इस जानी-पहचानी कमांड का इस्तेमाल करके, नया बाइनरी बनाया जा सकता है:
bazel build //main:hello-worldBazel, फिर से कुछ ऐसा आउटपुट जनरेट करता है:
INFO: Found 1 target...
Target //main:hello-world up-to-date:
bazel-bin/main/hello-world
INFO: Elapsed time: 2.399s, Critical Path: 0.30s
अब, हाल ही में बनाए गए बाइनरी की जांच की जा सकती है. इससे एक और "Hello
world" मिलता है:
bazel-bin/main/hello-worldअब अगर hello-greet.cc में बदलाव किया जाता है और प्रोजेक्ट को फिर से बनाया जाता है, तो Bazel सिर्फ़ उस फ़ाइल को फिर से कंपाइल करेगा.
डिपेंडेंसी ग्राफ़ को देखने पर, आपको पता चलेगा कि hello-world, hello-greet नाम के एक अतिरिक्त इनपुट पर निर्भर करता है:

खास जानकारी: स्टेज 2
अब आपने दो टारगेट वाला प्रोजेक्ट बना लिया है. hello-world टारगेट, एक सोर्स फ़ाइल बनाता है और किसी दूसरे टारगेट (//main:hello-greet) पर निर्भर करता है. यह टारगेट, दो अतिरिक्त सोर्स फ़ाइलें बनाता है. अगले सेक्शन में, एक और पैकेज जोड़ें.
तीसरा चरण: एक से ज़्यादा पैकेज
इस अगले चरण में, एक और लेयर जोड़ी जाती है. साथ ही, कई पैकेज वाला प्रोजेक्ट बनाया जाता है. cpp-tutorial/stage3 डायरेक्ट्री का स्ट्रक्चर और कॉन्टेंट देखें:
└──stage3
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
│ └── hello-time.h
└── MODULE.bazel
अब आपको दिखेगा कि दो सब-डायरेक्ट्री हैं और हर एक में BUILD फ़ाइल है. इसलिए, Bazel के लिए अब वर्कस्पेस में दो पैकेज हैं: lib और main.
lib/BUILD फ़ाइल देखें:
cc_library(
name = "hello-time",
srcs = ["hello-time.cc"],
hdrs = ["hello-time.h"],
visibility = ["//main:__pkg__"],
)
साथ ही, main/BUILD फ़ाइल में:
cc_library(
name = "hello-greet",
srcs = ["hello-greet.cc"],
hdrs = ["hello-greet.h"],
)
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
deps = [
":hello-greet",
"//lib:hello-time",
],
)
मुख्य पैकेज में मौजूद hello-world टारगेट, lib पैकेज में मौजूद hello-time टारगेट पर निर्भर करता है. इसलिए, टारगेट का लेबल //lib:hello-time है. Bazel को इस बारे में deps एट्रिब्यूट से पता चलता है. इसे डिपेंडेंसी ग्राफ़ में देखा जा सकता है:

बिल्ड को पूरा करने के लिए, विज़िबिलिटी एट्रिब्यूट का इस्तेमाल करके, lib/BUILD में मौजूद //lib:hello-time टारगेट को main/BUILD में मौजूद टारगेट के लिए साफ़ तौर पर दिखाया जाता है.
ऐसा इसलिए है, क्योंकि डिफ़ॉल्ट रूप से टारगेट सिर्फ़ उसी BUILD फ़ाइल में मौजूद अन्य टारगेट को दिखते हैं. Bazel, टारगेट विज़िबिलिटी का इस्तेमाल करता है. इससे, सार्वजनिक एपीआई में लागू करने से जुड़ी जानकारी वाली लाइब्रेरी लीक होने जैसी समस्याओं को रोकने में मदद मिलती है.
अब प्रोजेक्ट का यह फ़ाइनल वर्शन बनाएं. cpp-tutorial/stage3 डायरेक्ट्री पर स्विच करने के लिए, यह कमांड चलाएं:
cd ../stage3यहां दिया गया कमांड फिर से चलाएं:
bazel build //main:hello-worldBazel, इस तरह का कुछ आउटपुट जनरेट करता है:
INFO: Found 1 target...
Target //main:hello-world up-to-date:
bazel-bin/main/hello-world
INFO: Elapsed time: 0.167s, Critical Path: 0.00s
अब इस ट्यूटोरियल के आखिरी बाइनरी को टेस्ट करें, ताकि आपको फ़ाइनल Hello world मैसेज मिल सके:
bazel-bin/main/hello-worldखास जानकारी: स्टेज 3
अब आपने प्रोजेक्ट को दो पैकेज के तौर पर बनाया है. इनमें तीन टारगेट हैं. साथ ही, आपने इनके बीच की डिपेंडेंसी को समझ लिया है. इससे आपको आने वाले समय में Bazel की मदद से प्रोजेक्ट बनाने में मदद मिलेगी. अगले सेक्शन में, Bazel का इस्तेमाल जारी रखने का तरीका जानें.
अगले चरण
आपने Bazel की मदद से, पहला बुनियादी बिल्ड तैयार कर लिया है. हालांकि, यह सिर्फ़ शुरुआत है. Bazel के बारे में ज़्यादा जानने के लिए, यहाँ कुछ और संसाधन दिए गए हैं:
- C++ पर फ़ोकस बनाए रखने के लिए, C++ बिल्ड के इस्तेमाल के सामान्य उदाहरणों के बारे में पढ़ें.
- Bazel का इस्तेमाल करके अन्य ऐप्लिकेशन बनाने के लिए, Java, Android ऐप्लिकेशन या iOS ऐप्लिकेशन के ट्यूटोरियल देखें.
- लोकल और रिमोट रिपॉज़िटरी के साथ काम करने के बारे में ज़्यादा जानने के लिए, बाहरी डिपेंडेंसी के बारे में पढ़ें.
- Bazel के अन्य नियमों के बारे में ज़्यादा जानने के लिए, यह रेफ़रंस गाइड देखें.
बनाने का आनंद लें!