परिचय
क्या आपने पहले कभी 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 को बताती हैं कि प्रोजेक्ट के अलग-अलग हिस्सों को कैसे बिल्ड करना है. वर्कस्पेस में मौजूद कोई डायरेक्ट्री, जिसमें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 के संदर्भ में इनका क्या मतलब है. अगले सेक्शन में, आपको प्रोजेक्ट के पहले स्टेज को बिल्ड और टेस्ट करने का तरीका बताया जाएगा.
स्टेज 1: एक टारगेट, एक पैकेज
अब प्रोजेक्ट का पहला हिस्सा बिल्ड करने का समय आ गया है. विज़ुअल रेफ़रंस के लिए, प्रोजेक्ट के पहले स्टेज के सेक्शन का स्ट्रक्चर यहां दिया गया है:
examples
└── cpp-tutorial
└──stage1
├── main
│ ├── BUILD
│ └── hello-world.cc
└── WORKSPACE
cpp-tutorial/stage1 डायरेक्ट्री पर जाने के लिए, यह कमांड चलाएं:
cd cpp-tutorial/stage1इसके बाद, यह कमांड चलाएं:
bazel build //main:hello-worldटारगेट लेबल में, //main: हिस्सा, वर्कस्पेस के रूट के मुकाबले 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
अब आपने अपना पहला बिल्ड पूरा कर लिया है. इससे आपको यह बुनियादी जानकारी मिल गई है कि बिल्ड का स्ट्रक्चर कैसा होता है. अगले स्टेज में, एक और टारगेट जोड़कर, मुश्किल का लेवल बढ़ाया जाएगा.
स्टेज 2: कई बिल्ड टारगेट
छोटे प्रोजेक्ट के लिए, एक टारगेट काफ़ी होता है. हालांकि, बड़े प्रोजेक्ट को कई टारगेट और पैकेज में बांटा जा सकता है. इससे, इंक्रीमेंटल बिल्ड तेज़ी से किए जा सकते हैं. इसका मतलब है कि 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-worldएक बार फिर, Bazel कुछ ऐसा आउटपुट देता है:
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, पहले की तरह ही इनपुट पर निर्भर करता है. हालांकि, बिल्ड का स्ट्रक्चर अलग है:

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