परिचय
क्या आपने पहले कभी 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
│ └── WORKSPACE
├──stage2
│ ├── main
│ │ ├── BUILD
│ │ ├── hello-world.cc
│ │ ├── hello-greet.cc
│ │ └── hello-greet.h
│ └── WORKSPACE
└──stage3
├── main
│ ├── BUILD
│ ├── hello-world.cc
│ ├── hello-greet.cc
│ └── hello-greet.h
├── lib
│ ├── BUILD
│ ├── hello-time.cc
│ └── hello-time.h
└── WORKSPACE
फ़ाइलों के तीन सेट हैं. हर सेट, इस ट्यूटोरियल के एक चरण को दिखाता है. पहले चरण में, आपको एक पैकेज में मौजूद एक टारगेट बनाना होगा. दूसरे चरण में, आपको एक ही पैकेज से बाइनरी और लाइब्रेरी, दोनों बनानी होंगी. तीसरे और आखिरी चरण में, आपको कई पैकेज वाला एक प्रोजेक्ट बनाना होगा. साथ ही, इसे कई टारगेट के साथ बनाना होगा.
खास जानकारी: परिचय
Bazel और Git को इंस्टॉल करके और इस ट्यूटोरियल के लिए रिपॉज़िटरी को क्लोन करके, आपने Bazel के साथ अपनी पहली बिल्ड के लिए बुनियादी ढांचा तैयार कर लिया है. कुछ शब्दों को तय करने और अपना वर्कस्पेस सेट अप करने के लिए, अगले सेक्शन पर जाएं.
शुरू करना
Workspace सेट अप करना
कोई प्रोजेक्ट बनाने से पहले, आपको उसका वर्कस्पेस सेट अप करना होगा. वर्कस्पेस एक ऐसी डायरेक्ट्री होती है जिसमें आपके प्रोजेक्ट की सोर्स फ़ाइलें और Bazel के बिल्ड आउटपुट होते हैं. इसमें ये ज़रूरी फ़ाइलें भी शामिल हैं:
, जो डायरेक्ट्री और उसके कॉन्टेंट को Bazel वर्कस्पेस के तौर पर पहचानता है. यह प्रोजेक्ट के डायरेक्ट्री स्ट्रक्चर के रूट में मौजूद होता है.WORKSPACEfile- एक या उससे ज़्यादा
, जो Bazel को प्रोजेक्ट के अलग-अलग हिस्सों को बनाने का तरीका बताते हैं. Workspace में मौजूद वह डायरेक्ट्री जिसमेंBUILDfilesBUILDफ़ाइल होती है उसे पैकेज कहते हैं. (इस ट्यूटोरियल में, पैकेज के बारे में बाद में ज़्यादा जानकारी दी गई है.)
आने वाले समय में, किसी डायरेक्ट्री को Bazel वर्कस्पेस के तौर पर सेट करने के लिए, उस डायरेक्ट्री में WORKSPACE नाम की एक खाली फ़ाइल बनाएं. इस ट्यूटोरियल के लिए, हर स्टेज में WORKSPACE फ़ाइल पहले से मौजूद है.
NOTE: 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 rule को इंस्टैंशिएट करता है.
इस नियम से Bazel को यह निर्देश मिलता है कि वह hello-world.cc सोर्स फ़ाइल से, बिना किसी डिपेंडेंसी के एक एक्ज़ीक्यूटेबल बाइनरी बनाए.
खास जानकारी: शुरू करना
अब आपको कुछ मुख्य शब्दों के बारे में पता चल गया है. साथ ही, आपको यह भी पता चल गया है कि इस प्रोजेक्ट और Bazel के संदर्भ में उनका क्या मतलब है. अगले सेक्शन में, प्रोजेक्ट के पहले चरण को बनाया और टेस्ट किया जाएगा.
पहला चरण: एक टारगेट, एक पैकेज
अब प्रोजेक्ट का पहला हिस्सा बनाने का समय है. विज़ुअल रेफ़रंस के लिए, प्रोजेक्ट के पहले चरण के सेक्शन का स्ट्रक्चर यह है:
examples
└── cpp-tutorial
└──stage1
├── main
│ ├── BUILD
│ └── hello-world.cc
└── WORKSPACE
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
│ └── WORKSPACE
यहां 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 rule का इस्तेमाल किया जाता है. इसके बाद, 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-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
└── WORKSPACE
अब आपको दिखेगा कि दो सब-डायरेक्ट्री हैं और हर एक में 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 के अन्य नियमों के बारे में ज़्यादा जानने के लिए, यह रेफ़रंस गाइड देखें.
ऐप बनाने का आनंद लें!