शुरुआती जानकारी
क्या Bazel आपके लिए नया है? आप सही जगह पर हैं. Bazel को इस्तेमाल करने के बारे में आसान जानकारी पाने के लिए, 'फ़र्स्ट बिल्ड' ट्यूटोरियल देखें. इस ट्यूटोरियल में मुख्य शब्दों के बारे में बताया गया है, क्योंकि इन्हें Bazel के संदर्भ में इस्तेमाल किया गया है. साथ ही, इसमें आपको Bazel वर्कफ़्लो की बुनियादी बातें भी बताई गई हैं. पहले आपको ज़रूरी टूल की मदद से तीन प्रोजेक्ट बनाने और उन्हें चलाने की ज़रूरत है. साथ ही, यह भी जाना जा सकता है कि प्रोजेक्ट ज़्यादा जटिल कैसे और क्यों होते हैं.
Bazel एक बिल्ड सिस्टम है, जो बहु-भाषाओं वाले बिल्ड के साथ काम करता है. हालांकि, यह ट्यूटोरियल उदाहरण के तौर पर C++ प्रोजेक्ट का इस्तेमाल करता है. इसमें ऐसे सामान्य दिशा-निर्देश और फ़्लो बताया गया है जो ज़्यादातर भाषाओं पर लागू होते हैं.
पूरा होने का अनुमानित समय: 30 मिनट.
ज़रूरी शर्तें
अगर आपने पहले से Bzel इंस्टॉल नहीं किया है, तो अब उसे इंस्टॉल करें. यह ट्यूटोरियल सोर्स कंट्रोल के लिए 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) को इंस्टॉल करके और इस ट्यूटोरियल के लिए रिपॉज़िटरी को क्लोन करके, आपने Bzel के साथ अपने पहले बिल्ड की बुनियाद तैयार कर ली है. कुछ शर्तों के बारे में बताने और अपना फ़ाइल फ़ोल्डर सेट अप करने के लिए, अगले सेक्शन पर जाएं.
रिपोर्ट का इस्तेमाल करना
वर्कस्पेस सेट अप करना
प्रोजेक्ट बनाने से पहले, आपको इसका फ़ाइल फ़ोल्डर सेट अप करना होगा. वर्कस्पेस एक डायरेक्ट्री है, जिसमें आपके प्रोजेक्ट की सोर्स फ़ाइलें और Bazel के बिल्ड आउटपुट होते हैं. इसमें ये अहम फ़ाइलें भी शामिल हैं:
, जो डायरेक्ट्री और उसके कॉन्टेंट की पहचान, Bazel फ़ाइल फ़ोल्डर के तौर पर करती है. साथ ही, यह प्रोजेक्ट की डायरेक्ट्री स्ट्रक्चर के रूट में रहती है.WORKSPACE
file- एक या एक से ज़्यादा
, जो बैजल को प्रोजेक्ट के अलग-अलग हिस्से बनाने का तरीका बताते हैं. फ़ाइल फ़ोल्डर में मौजूद जिस डायरेक्ट्री मेंBUILD
filesBUILD
फ़ाइल होती है वह पैकेज होता है. (इस ट्यूटोरियल में बाद में पैकेज के बारे में ज़्यादा जानकारी दी गई है.)
आने वाले प्रोजेक्ट में, किसी डायरेक्ट्री को Bazel फ़ाइल फ़ोल्डर के तौर पर सेट करने के लिए, उस डायरेक्ट्री में WORKSPACE
नाम से एक खाली फ़ाइल बनाएं. इस ट्यूटोरियल में, हर चरण में एक WORKSPACE
फ़ाइल पहले से मौजूद होती है.
ध्यान दें: जब 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:
हिस्सा फ़ाइल फ़ोल्डर के रूट के हिसाब से 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
” मैसेज दिखता है.
यहां पहले चरण का डिपेंडेंसी ग्राफ़ दिया गया है:
खास जानकारी: पहला चरण
अपना पहला बिल्ड पूरा कर लेने के बाद, आपको इस बारे में बुनियादी जानकारी मिलेगी कि बिल को कैसे व्यवस्थित किया गया है. अगले चरण में, एक और टारगेट जोड़कर जटिलता भी जोड़ी जा सकती है.
दूसरा चरण: एक से ज़्यादा बिल्ड टारगेट
हालांकि, छोटे प्रोजेक्ट के लिए एक टारगेट काफ़ी होता है, लेकिन हो सकता है कि आप बड़े प्रोजेक्ट को कई टारगेट और पैकेज में बांटना चाहें. इसकी मदद से, तेज़ी से इंक्रीमेंटल बिल्ड मिलते हैं – इसका मतलब है कि 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
एक बार फिर, बेज़ेल ने कुछ ऐसा बनाया:
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
) पर निर्भर करता है, जो दो अतिरिक्त सोर्स फ़ाइलें बनाता है. अगले सेक्शन में, इसे एक कदम आगे ले जाएं और दूसरा पैकेज जोड़ें.
तीसरा चरण: एक से ज़्यादा पैकेज
इस अगले चरण में, Android घड़ी के विजेट के लिए एक और लेयर जोड़ी गई है और कई पैकेज वाला प्रोजेक्ट बनाया गया है. 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-world
Bazel कुछ ऐसा बनाता है:
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
खास जानकारी: तीसरा चरण
अब आपने इस प्रोजेक्ट को दो पैकेज के तौर पर तैयार कर लिया है और आप दोनों के बीच की डिपेंडेंसी समझते हैं. इससे आपको Bazel के साथ आगे बढ़ने और आने वाले प्रोजेक्ट बनाने में मदद मिलती है. अगले सेक्शन में, Bazel का सफ़र जारी रखने के बारे में जानें.
अगले चरण
आपने Bazel के साथ अपना पहला बेसिक बिल्ड पूरा कर लिया है, लेकिन यह अभी शुरुआत ही है. Bazel के साथ सीखना जारी रखने के लिए, यहां कुछ और संसाधन दिए गए हैं:
- C++ पर ध्यान देते रहने के लिए, C++ के बिल्ड इस्तेमाल के सामान्य उदाहरणों के बारे में पढ़ें.
- Bazel के साथ दूसरे ऐप्लिकेशन बनाने के लिए, Java, Android ऐप्लिकेशन या iOS ऐप्लिकेशन के ट्यूटोरियल देखें.
- लोकल और रिमोट डेटा स्टोर करने की जगहों के साथ काम करने के बारे में ज़्यादा जानने के लिए, बाहरी डिपेंडेंसी के बारे में पढ़ें.
- बेज़ेल के दूसरे नियमों के बारे में ज़्यादा जानने के लिए, यह रेफ़रंस गाइड देखें.
बिल्डिंग मुबारक!