परिचय
क्या आपने पहले कभी 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 की मदद से पहली बार बिल्ड करने में मदद मिलेगी. कुछ शब्दों को तय करने और अपना वर्कस्पेस सेट अप करने के लिए, अगले सेक्शन पर जाएं.
शुरू करना
वर्कस्पेस सेट अप करना
कोई प्रोजेक्ट बनाने से पहले, आपको उसका वर्कस्पेस सेट अप करना होगा. वर्कस्पेस एक ऐसी डायरेक्ट्री होती है जिसमें आपके प्रोजेक्ट की सोर्स फ़ाइलें और 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-greet नाम के एक अतिरिक्त इनपुट पर निर्भर करता है:

खास जानकारी: दूसरा चरण
अब आपने दो टारगेट वाला प्रोजेक्ट बना लिया है. hello-world टारगेट, एक सोर्स फ़ाइल बनाता है और किसी दूसरे टारगेट (//main:hello-greet) पर निर्भर होता है. //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 के अन्य नियमों के बारे में ज़्यादा जानने के लिए, यह रेफ़रंस गाइड देखें.
बनाने का आनंद लें!