परिचय
क्या आपने पहले कभी Bazel का इस्तेमाल नहीं किया है? आप सही जगह पर हैं. Bazel का इस्तेमाल करने के बारे में आसानी से जानने के लिए, पहला बिल्ड ट्यूटोरियल देखें. इस ट्यूटोरियल में मुख्य शब्दों के बारे में बताया गया है, क्योंकि उनका इस्तेमाल Baze के कॉन्टेक्स्ट में किया गया है. साथ ही, इसमें आपको Basel के वर्कफ़्लो की बुनियादी बातें भी बताई गई हैं. आपको जिन टूल की ज़रूरत है उनसे शुरू करके, आपको तीन प्रोजेक्ट बनाने और चलाने होंगे. इन प्रोजेक्ट की जटिलता बढ़ती जाएगी. साथ ही, आपको यह भी पता चलेगा कि ये प्रोजेक्ट कैसे और क्यों जटिल होते हैं.
Baज़ल एक बिल्ड सिस्टम है, जो कई भाषाओं में वीडियो बनाने की सुविधा देता है. इस ट्यूटोरियल में 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
फ़ाइलों के तीन सेट हैं. हर सेट, इस ट्यूटोरियल के किसी चरण को दिखाता है. पहले चरण में, आपको किसी एक पैकेज में मौजूद कोई टारगेट बनाना होगा. दूसरे चरण में, आपको एक ही पैकेज से बाइनरी और लाइब्रेरी, दोनों बनानी होंगी. तीसरे और आखिरी चरण में, आपको एक से ज़्यादा पैकेज वाला प्रोजेक्ट बनाना होगा और उसे एक से ज़्यादा टारगेट के लिए बनाना होगा.
खास जानकारी: परिचय
Basel (और Git) को इंस्टॉल करके और इस ट्यूटोरियल के लिए रिपॉज़िटरी की क्लोनिंग करके, आपने Bazel के साथ अपने पहले बिल्ड की बुनियाद तैयार कर ली है. कुछ शब्दों की परिभाषा देने और अपना वर्कस्पेस सेट अप करने के लिए, अगले सेक्शन पर जाएं.
शुरू करना
फ़ाइल फ़ोल्डर सेट अप करना
प्रोजेक्ट बनाने से पहले, आपको उसका वर्कस्पेस सेट अप करना होगा. वर्कस्पेस एक डायरेक्ट्री होती है, जिसमें आपके प्रोजेक्ट की सोर्स फ़ाइलें और बेज़ल के बिल्ड आउटपुट मौजूद होते हैं. इसमें ये अहम फ़ाइलें भी शामिल हैं:
, डायरेक्ट्री और उसके कॉन्टेंट की पहचान बेज़ल वर्कस्पेस के तौर पर करता है. साथ ही, यह प्रोजेक्ट की डायरेक्ट्री स्ट्रक्चर के रूट में मौजूद होता है.WORKSPACE
file- एक या एक से ज़्यादा
, जो Bazel को प्रोजेक्ट के अलग-अलग हिस्सों को बनाने का तरीका बताते हैं. Workspace में मौजूद ऐसी डायरेक्ट्री जिसमेंBUILD
filesBUILD
फ़ाइल हो, उसे पैकेज कहा जाता है. (पैकेज के बारे में ज़्यादा जानकारी, इस ट्यूटोरियल में आगे दी गई है.)
आने वाले समय में, किसी डायरेक्ट्री को Bazel वर्कस्पेस के तौर पर सेट करने के लिए, उस डायरेक्ट्री में WORKSPACE
नाम की खाली फ़ाइल बनाएं. इस ट्यूटोरियल के लिए,
हर चरण में एक WORKSPACE
फ़ाइल पहले से मौजूद है.
ध्यान दें: Basel का प्रोजेक्ट बनाते समय, सभी इनपुट एक ही वर्कस्पेस में होने चाहिए. अलग-अलग फ़ाइल फ़ोल्डर में मौजूद फ़ाइलें, एक-दूसरे से अलग होती हैं. ऐसा तब तक होता है, जब तक उन्हें लिंक न किया गया हो. फ़ाइल फ़ोल्डर के नियमों के बारे में ज़्यादा जानकारी इस गाइड में मिल सकती है.
BUILD फ़ाइल को समझना
BUILD
फ़ाइल में, Bazel के लिए कई तरह के निर्देश होते हैं. हर BUILD
फ़ाइल के लिए, निर्देशों के सेट के तौर पर कम से कम एक नियम होना ज़रूरी है. इससे Bazel को, अपनी पसंद के आउटपुट बनाने का तरीका पता चलता है. जैसे, एक्ज़ीक्यूटेबल बाइनरी या लाइब्रेरी. BUILD
फ़ाइल में बिल्ड नियम के हर इंस्टेंस को टारगेट कहा जाता है. यह सोर्स फ़ाइलों और डिपेंडेंसी के खास सेट के बारे में बताता है.
टारगेट, दूसरे टारगेट पर भी ले जा सकता है.
cpp-tutorial/stage1/main
डायरेक्ट्री में मौजूद BUILD
फ़ाइल पर एक नज़र डालें:
cc_binary(
name = "hello-world",
srcs = ["hello-world.cc"],
)
हमारे उदाहरण में, hello-world
टारगेट, Basel के बिल्ट-इन को इंस्टैंशिएट करता है
cc_binary rule
.
यह नियम, बेज़ल को 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
फ़ाइल में टारगेट का नाम है.
बेज़ल कुछ ऐसा बनाते हैं जो कुछ ऐसा दिखता है:
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
आपने अभी-अभी अपना पहला Basel टारगेट बनाया है. Basel जगह, आउटपुट को फ़ाइल फ़ोल्डर के रूट में 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
फिर से, 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
में बदलाव किया जाता है और प्रोजेक्ट को फिर से बनाया जाता है, तो Basel, उस फ़ाइल को सिर्फ़
रीकंपाइल करता है.
डिपेंडेंसी ग्राफ़ को देखकर, यह पता चलता है कि 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
खास जानकारी: तीसरा चरण
अब आपने प्रोजेक्ट को तीन टारगेट के साथ दो पैकेज के तौर पर बना लिया है और दोनों के बीच की निर्भरताओं को समझ लिया है. इससे आपको Basel की मदद से, आने वाले समय में प्रोजेक्ट बनाने में मदद मिलती है. अगले सेक्शन में, Bazel के साथ अपनी यात्रा जारी रखने का तरीका जानें.
अगले चरण
आपने Bazel की मदद से अपना पहला बुनियादी बिल्ड पूरा कर लिया है. हालांकि, यह सिर्फ़ शुरुआत है. Bazel के बारे में ज़्यादा जानने के लिए, यहां कुछ और संसाधन दिए गए हैं:
- C++ पर ध्यान देते रहने के लिए, C++ बिल्ड के इस्तेमाल के सामान्य उदाहरण के बारे में पढ़ें.
- Bazel की मदद से अन्य ऐप्लिकेशन बनाने के लिए, Java, Android ऐप्लिकेशन या iOS ऐप्लिकेशन के लिए ट्यूटोरियल देखें.
- लोकल और रिमोट डेटा स्टोर करने की जगहों के साथ काम करने के बारे में ज़्यादा जानने के लिए, बाहरी डिपेंडेंसी के बारे में पढ़ें.
- Bazel के अन्य नियमों के बारे में ज़्यादा जानने के लिए, यह रेफ़रंस गाइड देखें.
मज़े से बनाएं!