इस ट्यूटोरियल में Java एप्लिकेशन बनाने की बेसिक बातों को कवर किया गया है
बेज़ल. आपको अपना फ़ाइल फ़ोल्डर सेट अप करना होगा और एक आसान Java प्रोजेक्ट बनाना होगा,
बेज़ेल के मुख्य सिद्धांतों की जानकारी देता है, जैसे कि टारगेट और BUILD
फ़ाइलें.
पूरा होने का अनुमानित समय: 30 मिनट.
आप इन चीज़ों के बारे में जानेंगे
इस ट्यूटोरियल में आपको ये काम करने का तरीका पता चलेगा:
- कोई टारगेट बनाएं
- प्रोजेक्ट की डिपेंडेंसी को विज़ुअलाइज़ करना
- प्रोजेक्ट को कई टारगेट और पैकेज में बांटें
- सभी पैकेज में टारगेट विज़िबिलिटी को कंट्रोल करें
- लेबल के ज़रिए संदर्भ लक्ष्य
- टारगेट डिप्लॉय करना
शुरू करने से पहले
Basel इंस्टॉल करें
ट्यूटोरियल की तैयारी करने के लिए, पहले Basel को इंस्टॉल करें अगर आपने इसे पहले से इंस्टॉल नहीं किया है.
JDK इंस्टॉल करें
Java JDK इंस्टॉल करें (पसंदीदा वर्शन 11 है, हालांकि 8 और 15 के बीच के वर्शन काम करते हैं).
JDK पर पॉइंट करने के लिए, JAVA_HOME एनवायरमेंट वैरिएबल को सेट करें.
Linux/macOS पर:
export JAVA_HOME="$(dirname $(dirname $(realpath $(which javac))))"
Windows पर:
- कंट्रोल पैनल खोलें.
- "सिस्टम और सुरक्षा" पर जाएं > "सिस्टम" > "बेहतर सिस्टम सेटिंग" > "ऐडवांस सेटिंग" टैब > "एनवायरमेंट वैरिएबल..." .
- "उपयोगकर्ता वैरिएबल" में सूची (सबसे ऊपर मौजूद), "नया..." पर क्लिक करें.
- "वैरिएबल का नाम" फ़ील्ड में,
JAVA_HOME
डालें. - "डायरेक्ट्री ब्राउज़ करें..." पर क्लिक करें.
- JDK डायरेक्ट्री पर जाएं (जैसे,
C:\Program Files\Java\jdk1.8.0_152
). - "ठीक है" पर क्लिक करें सभी डायलॉग विंडो पर.
सैंपल प्रोजेक्ट डाउनलोड करें
Baज़ल के GitHub रिपॉज़िटरी से सैंपल प्रोजेक्ट को वापस पाएं:
git clone https://github.com/bazelbuild/examples
इस ट्यूटोरियल के लिए सैंपल प्रोजेक्ट, examples/java-tutorial
में है
डायरेक्ट्री इस तरह बनाई गई है:
java-tutorial
├── BUILD
├── src
│ └── main
│ └── java
│ └── com
│ └── example
│ ├── cmdline
│ │ ├── BUILD
│ │ └── Runner.java
│ ├── Greeting.java
│ └── ProjectRunner.java
└── MODULE.bazel
बेज़ल के साथ बिल्ड
फ़ाइल फ़ोल्डर सेट अप करना
प्रोजेक्ट बनाने से पहले, आपको उसका फ़ाइल फ़ोल्डर सेट अप करना होगा. फ़ाइल फ़ोल्डर है एक डायरेक्ट्री, जिसमें आपके प्रोजेक्ट की सोर्स फ़ाइलें और Basel के बिल्ड आउटपुट मौजूद होते हैं. यह इसमें ऐसी फ़ाइलें भी शामिल होती हैं जिन्हें बेज़ल खास के तौर पर पहचानता है:
MODULE.bazel
फ़ाइल, जो डायरेक्ट्री और उसके कॉन्टेंट की पहचान बेज़ल वर्कस्पेस और प्रोजेक्ट की डायरेक्ट्री स्ट्रक्चर के मूल में मौजूद है,एक या एक से ज़्यादा
BUILD
फ़ाइलें, जो BaZ को बताती हैं कि ब्राउज़र के अलग-अलग हिस्से कैसे बनाए जाएं को भी शामिल किया है. (Workspace में मौजूद एक डायरेक्ट्री, जिसमेंBUILD
फ़ाइल है एक पैकेज है. इस ट्यूटोरियल में आपको बाद में पैकेज के बारे में जानकारी दी जाएगी.)
किसी डायरेक्ट्री को बेज़ल वर्कस्पेस के तौर पर दिखाने के लिए, नाम की एक खाली फ़ाइल बनाएं
MODULE.bazel
उस डायरेक्ट्री में मौजूद हैं.
जब Basel का प्रोजेक्ट बनाया जाता है, तब सभी इनपुट और डिपेंडेंसी एक जैसी होनी चाहिए name@yourcompany.com जैसा कोई प्रोफ़ेशनल ईमेल पता बनाएं. इससे आपका कारोबार ज़्यादा भरोसेमंद बनेगा. अलग-अलग फ़ाइल फ़ोल्डर में मौजूद फ़ाइलें, एक से अलग होती हैं जब तक कि कोई अन्य प्लैटफ़ॉर्म लिंक न किया गया हो. इस ट्यूटोरियल में इनके बारे में बताया नहीं जा सकता.
BUILD फ़ाइल को समझें
BUILD
फ़ाइल में Basel के लिए कई अलग-अलग तरह के निर्देश होते हैं.
सबसे ज़रूरी टाइप बिल्ड नियम है, जो बेज़ल को बताता है कि
एक्ज़ीक्यूट किए जा सकने वाले बाइनरी या लाइब्रेरी जैसे आउटपुट के लिए इस्तेमाल कर सकते हैं. हर इंस्टेंस
BUILD
फ़ाइल में बिल्ड नियम को टारगेट कहा जाता है और
सोर्स फ़ाइलों और डिपेंडेंसी के एक खास सेट की ज़रूरत होती है. टारगेट, दूसरे
टारगेट के लिए.
java-tutorial/BUILD
फ़ाइल पर एक नज़र डालें:
java_binary(
name = "ProjectRunner",
srcs = glob(["src/main/java/com/example/*.java"]),
)
हमारे उदाहरण में, ProjectRunner
टारगेट, Baze के बिल्ट-इन को इंस्टैंशिएट करता है
java_binary
नियम. नियम बेज़ल को यह बताता है कि
.jar
फ़ाइल और रैपर शेल स्क्रिप्ट बनाएं (दोनों को टारगेट के नाम पर नाम दिया गया है).
टारगेट में मौजूद एट्रिब्यूट, इसकी निर्भरता और विकल्पों के बारे में साफ़ तौर पर बताते हैं.
name
एट्रिब्यूट ज़रूरी है, लेकिन कई एट्रिब्यूट ज़रूरी नहीं हैं. उदाहरण के लिए,
ProjectRunner
नियम का टारगेट, name
टारगेट का नाम है, srcs
से पता चलता है
ऐसी सोर्स फ़ाइलें जिनका इस्तेमाल Basel ने टारगेट बनाने के लिए किया है. साथ ही, main_class
से पता चलता है कि
वह क्लास जिसमें मुख्य तरीका होता है. (आपने देखा होगा कि हमारा उदाहरण
स्रोत फ़ाइलों के सेट को Basel में भेजने के लिए, GLb का इस्तेमाल करता है
उन्हें एक-एक करके दिखाने के बजाय.)
प्रोजेक्ट बनाएं
सैंपल प्रोजेक्ट बनाने के लिए, java-tutorial
डायरेक्ट्री पर जाएं
और चलाएं:
bazel build //:ProjectRunner
टारगेट लेबल में, //
वाला हिस्सा, BUILD
फ़ाइल की जगह होता है
फ़ाइल फ़ोल्डर के रूट से मिलता-जुलता है (इस मामले में, रूट).
और BUILD
फ़ाइल में टारगेट का नाम ProjectRunner
है. (आपको
इस ट्यूटोरियल के आखिर में, टारगेट लेबल के बारे में ज़्यादा जानकारी पाएं.)
Baज़ल, इस तरह के आउटपुट देता है:
INFO: Found 1 target...
Target //:ProjectRunner up-to-date:
bazel-bin/ProjectRunner.jar
bazel-bin/ProjectRunner
INFO: Elapsed time: 1.021s, Critical Path: 0.83s
बधाई हो, आपने अभी-अभी अपना पहला Bagel टारगेट बनाया है! बेज़ल जगहें बिल्ड
bazel-bin
डायरेक्ट्री के आउटपुट के लिए, फ़ाइल फ़ोल्डर के रूट पर जाएं. ब्राउज़ करें
इसकी सामग्री के ज़रिए बेज़ेल के आउटपुट स्ट्रक्चर के बारे में आइडिया लोगों तक जाता है.
अब अपनी हाल ही में बनाई गई बाइनरी की जांच करें:
bazel-bin/ProjectRunner
डिपेंडेंसी ग्राफ़ देखें
Basel के लिए बिल्ड डिपेंडेंसी का इस्तेमाल, BUILD फ़ाइलों में साफ़ तौर पर करना ज़रूरी होता है. Basel इन स्टेटमेंट का इस्तेमाल प्रोजेक्ट का डिपेंडेंसी ग्राफ़ बनाने के लिए करता है, जो सटीक इंक्रीमेंटल बिल्ड को चालू करता है.
सैंपल प्रोजेक्ट की डिपेंडेंसी को विज़ुअलाइज़ करने के लिए, टेक्स्ट जनरेट किया जा सकता है इस कमांड को चलाकर डिपेंडेंसी ग्राफ़ का फ़ाइल फ़ोल्डर रूट:
bazel query --notool_deps --noimplicit_deps "deps(//:ProjectRunner)" --output graph
ऊपर दिया गया निर्देश बेज़ल को टारगेट के लिए सभी डिपेंडेंसी खोजने के लिए कहता है
//:ProjectRunner
(होस्ट और इंप्लिसिट डिपेंडेंसी को छोड़कर) और
आउटपुट को ग्राफ़ के रूप में देखना.
इसके बाद, टेक्स्ट को GraphViz में चिपकाएं.
जैसा कि आपको दिख रहा है, प्रोजेक्ट का एक ही टारगेट है, जो कोई अतिरिक्त निर्भरता नहीं:
अपना फ़ाइल फ़ोल्डर सेट अप करने के बाद, अपना प्रोजेक्ट बनाएं और उसकी जांच करें डिपेंडेंसी जोड़ें, तो कुछ जटिलता जोड़ी जा सकती है.
अपने Basel के बिल्ड को बेहतर बनाएं
छोटे प्रोजेक्ट के लिए एक ही टारगेट काफ़ी होता है. हालांकि, हो सकता है कि कई टारगेट और पैकेज के लिए बड़े प्रोजेक्ट को बनाया गया है. इससे इन प्रोजेक्ट को तेज़ी से बढ़ाने में मदद मिलती है बिल्ड (इसका मतलब है कि जो बदलाव हुए हैं उन्हें फिर से बनाएं) और एक ही बार में प्रोजेक्ट के कई हिस्से तैयार करना.
कई बिल्ड टारगेट तय करें
सैंपल प्रोजेक्ट के बिल्ड को दो टारगेट में बांटा जा सकता है. इसकी सामग्री बदलें
java-tutorial/BUILD
फ़ाइल में ये शामिल हैं:
java_binary(
name = "ProjectRunner",
srcs = ["src/main/java/com/example/ProjectRunner.java"],
main_class = "com.example.ProjectRunner",
deps = [":greeter"],
)
java_library(
name = "greeter",
srcs = ["src/main/java/com/example/Greeting.java"],
)
इस कॉन्फ़िगरेशन के साथ, Basel सबसे पहले greeter
लाइब्रेरी बनाता है,
ProjectRunner
बाइनरी. java_binary
में deps
एट्रिब्यूट से बेज़ल को यह पता चलता है कि
ProjectRunner
बाइनरी बनाने के लिए, greeter
लाइब्रेरी ज़रूरी है.
प्रोजेक्ट के इस नए वर्शन को बनाने के लिए, यह कमांड चलाएं:
bazel build //:ProjectRunner
Baज़ल, इस तरह के आउटपुट देता है:
INFO: Found 1 target...
Target //:ProjectRunner up-to-date:
bazel-bin/ProjectRunner.jar
bazel-bin/ProjectRunner
INFO: Elapsed time: 2.454s, Critical Path: 1.58s
अब अपनी हाल ही में बनाई गई बाइनरी की जांच करें:
bazel-bin/ProjectRunner
अगर अब ProjectRunner.java
में बदलाव किया जाता है और प्रोजेक्ट को फिर से बनाया जाता है, तो सिर्फ़ Basel का इस्तेमाल किया जाएगा
उस फ़ाइल को फिर से कंपाइल करता है.
डिपेंडेंसी ग्राफ़ में देखा जा सकता है कि ProjectRunner
,
ये पहले की तरह ही इनपुट हैं, लेकिन बिल्ड का स्ट्रक्चर अलग है:
अब आपने दो टारगेट के साथ प्रोजेक्ट बना लिया है. ProjectRunner
टारगेट बनाता है
और एक अन्य टारगेट (:greeter
) पर निर्भर होगा, जो
एक अतिरिक्त सोर्स फ़ाइल का इस्तेमाल करें.
एक से ज़्यादा पैकेज का इस्तेमाल करें
अब प्रोजेक्ट को कई पैकेज में बांट लें. अगर आपको इन बातों पर एक नज़र
src/main/java/com/example/cmdline
डायरेक्ट्री, आप देख सकते हैं कि इसमें ये भी शामिल हैं
BUILD
फ़ाइल और कुछ सोर्स फ़ाइलें. इसलिए, Babel के लिए अब कार्य क्षेत्र
इसमें दो पैकेज, //src/main/java/com/example/cmdline
और //
शामिल हैं (इस समय से
फ़ाइल फ़ोल्डर के रूट में एक BUILD
फ़ाइल है).
src/main/java/com/example/cmdline/BUILD
फ़ाइल पर एक नज़र डालें:
java_binary(
name = "runner",
srcs = ["Runner.java"],
main_class = "com.example.cmdline.Runner",
deps = ["//:greeter"],
)
runner
टारगेट, //
पैकेज में मौजूद greeter
टारगेट पर निर्भर करता है. इसलिए,
टारगेट लेबल //:greeter
) - बेज़ल, इसे deps
एट्रिब्यूट के ज़रिए जानते हैं.
डिपेंडेंसी ग्राफ़ पर एक नज़र डालें:
हालांकि, बिल्ड को सफल बनाने के लिए, आपको साफ़ तौर पर runner
टारगेट देना होगा
में टारगेट के लिए, //src/main/java/com/example/cmdline/BUILD
विज़िबिलिटी में
visibility
एट्रिब्यूट का इस्तेमाल करके //BUILD
. ऐसा डिफ़ॉल्ट टारगेट से होता है
केवल उसी BUILD
फ़ाइल में मौजूद अन्य लक्ष्यों को दिखाई देते हैं. (Baze टारगेट का इस्तेमाल करता है
ताकि लागू करने की जानकारी वाली लाइब्रेरी जैसी समस्याओं को रोका जा सके
सार्वजनिक एपीआई में लीक हो रहा है.)
ऐसा करने के लिए, यहां visibility
एट्रिब्यूट को greeter
टारगेट में जोड़ें
java-tutorial/BUILD
, जैसा कि नीचे दिखाया गया है:
java_library(
name = "greeter",
srcs = ["src/main/java/com/example/Greeting.java"],
visibility = ["//src/main/java/com/example/cmdline:__pkg__"],
)
अब रूट पर नीचे दिए गए कमांड को चलाकर नया पैकेज बनाया जा सकता है का तरीका:
bazel build //src/main/java/com/example/cmdline:runner
Baज़ल, इस तरह के आउटपुट देता है:
INFO: Found 1 target...
Target //src/main/java/com/example/cmdline:runner up-to-date:
bazel-bin/src/main/java/com/example/cmdline/runner.jar
bazel-bin/src/main/java/com/example/cmdline/runner
INFO: Elapsed time: 1.576s, Critical Path: 0.81s
अब अपनी हाल ही में बनाई गई बाइनरी की जांच करें:
./bazel-bin/src/main/java/com/example/cmdline/runner
अब आपने प्रोजेक्ट में बदलाव किया है, ताकि इसे दो पैकेज के तौर पर बनाया जा सके. हर पैकेज में एक पैकेज शामिल है और उनके बीच की निर्भरता को समझ सकते हैं.
टारगेट का रेफ़रंस देने के लिए लेबल का इस्तेमाल करना
BUILD
फ़ाइलों में और कमांड लाइन पर, Baze चैनल की तरफ़ से रेफ़रंस के लिए टारगेट लेबल का इस्तेमाल किया जाता है
टारगेट - उदाहरण के लिए, //:ProjectRunner
या
//src/main/java/com/example/cmdline:runner
. उनका सिंटैक्स इस तरह है:
//path/to/package:target-name
अगर टारगेट, नियम के हिसाब से टारगेट है, तो path/to/package
डायरेक्ट्री जिसमें BUILD
फ़ाइल शामिल है और target-name
वही नाम है जिसे आपने
टारगेट BUILD
फ़ाइल में (name
एट्रिब्यूट). अगर टारगेट कोई फ़ाइल है
टारगेट करता है, तो path/to/package
पैकेज के रूट का पाथ होता है और
target-name
, टारगेट फ़ाइल का नाम होता है. इसमें इसका पूरा पाथ भी शामिल होता है.
रिपॉज़िटरी रूट पर टारगेट का रेफ़रंस देते समय, पैकेज पाथ खाली होता है,
बस //:target-name
का इस्तेमाल करें. एक ही BUILD
में मौजूद टारगेट का रेफ़रंस देते समय
फ़ाइल में, आप //
फ़ाइल फ़ोल्डर रूट आइडेंटिफ़ायर को छोड़ सकते हैं और
:target-name
.
उदाहरण के लिए, java-tutorial/BUILD
फ़ाइल में मौजूद टारगेट के लिए, आपको ये काम नहीं करने थे
पैकेज पाथ की जानकारी दें, क्योंकि फ़ाइल फ़ोल्डर रूट खुद एक पैकेज (//
) है, और
आपके दो टारगेट लेबल सिर्फ़ //:ProjectRunner
और //:greeter
थे.
हालांकि, //src/main/java/com/example/cmdline/BUILD
फ़ाइल में मौजूद लक्ष्यों के लिए
//src/main/java/com/example/cmdline
का पूरा पैकेज पाथ बताना था
और आपका टारगेट लेबल //src/main/java/com/example/cmdline:runner
था.
डिप्लॉयमेंट के लिए Java टारगेट पैकेज करना
चलिए, अब डिप्लॉयमेंट के लिए Java टारगेट पैकेज करते हैं. इसके लिए, बाइनरी इसके रनटाइम डिपेंडेंसी के हिसाब से काम करता है. इससे आप बाइनरी को अपने डेवलपमेंट एनवायरमेंट होने चाहिए.
जैसा कि आपको याद है, java_binary बिल्ड नियम
.jar
और एक रैपर शेल स्क्रिप्ट जनरेट करता है. इसके कॉन्टेंट को देखें
इस निर्देश का इस्तेमाल करके runner.jar
:
jar tf bazel-bin/src/main/java/com/example/cmdline/runner.jar
कॉन्टेंट हैं:
META-INF/
META-INF/MANIFEST.MF
com/
com/example/
com/example/cmdline/
com/example/cmdline/Runner.class
runner.jar
में Runner.class
मौजूद है, लेकिन यह इस पर निर्भर नहीं है.
Greeting.class
. Basel की जनरेट की गई runner
स्क्रिप्ट में greeter.jar
जुड़ती है
क्लासपाथ से जोड़ा जा सकता है, इसलिए अगर आप उसे ऐसे छोड़ देते हैं, तो वह स्थानीय तौर पर चलेगा, लेकिन
अन्य मशीन पर स्टैंडअलोन नहीं चलेगा. अच्छी बात यह है कि java_binary
नियम
आपको सेल्फ़-कंटेन्ड और डिप्लॉयेबल बाइनरी बनाने की अनुमति देता है. इसे बनाने के लिए, जोड़ें
टारगेट नाम के लिए _deploy.jar
:
bazel build //src/main/java/com/example/cmdline:runner_deploy.jar
Baज़ल, इस तरह के आउटपुट देता है:
INFO: Found 1 target...
Target //src/main/java/com/example/cmdline:runner_deploy.jar up-to-date:
bazel-bin/src/main/java/com/example/cmdline/runner_deploy.jar
INFO: Elapsed time: 1.700s, Critical Path: 0.23s
आपने अभी-अभी runner_deploy.jar
बनाया है. इसे अलग से भी इस्तेमाल किया जा सकता है
आपका डेवलपमेंट एनवायरमेंट है, क्योंकि इसमें ज़रूरी रनटाइम शामिल है
निर्भरता. इस स्टैंडअलोन JAR का कॉन्टेंट देखें. इसके लिए
पहले की तरह ही आदेश:
jar tf bazel-bin/src/main/java/com/example/cmdline/runner_deploy.jar
कॉन्टेंट में सभी ज़रूरी क्लास के बारे में बताया गया है:
META-INF/
META-INF/MANIFEST.MF
build-data.properties
com/
com/example/
com/example/cmdline/
com/example/cmdline/Runner.class
com/example/Greeting.class
इसके बारे में और पढ़ें
ज़्यादा जानकारी के लिए, यह देखें:
इसके लिए rules_jvm_external ये नियम, ट्रांज़िटिव Maven डिपेंडेंसी मैनेज करने के लिए बनाए गए हैं.
बाहरी डिपेंडेंसी के साथ काम करने के बारे में ज़्यादा जानने के लिए डेटा स्टोर करने की जगहें.
बेज़ल के बारे में ज़्यादा जानने के लिए, अन्य नियम.
बिल्डिंग बनाने के लिए, C++ का बिल्ड ट्यूटोरियल बेज़ल के साथ C++ प्रोजेक्ट.
Android ऐप्लिकेशन ट्यूटोरियल और iOS ऐप्लिकेशन ट्यूटोरियल) से भी मदद ली जा सकती है Basel की मदद से, Android और iOS के लिए मोबाइल ऐप्लिकेशन बना रही है.
बिल्डिंग बनाने के लिए शुभकामनाएं!