এই টিউটোরিয়ালটি Bazel-এর সাহায্যে জাভা অ্যাপ্লিকেশান তৈরির মূল বিষয়গুলি কভার করে৷ আপনি আপনার ওয়ার্কস্পেস সেট আপ করবেন এবং একটি সাধারণ জাভা প্রকল্প তৈরি করবেন যা মূল বেজেল ধারণাগুলি যেমন লক্ষ্য এবং BUILD ফাইলগুলিকে চিত্রিত করে।
আনুমানিক সমাপ্তির সময়: 30 মিনিট।
আপনি কি শিখবেন
এই টিউটোরিয়ালে আপনি শিখবেন কিভাবে:
- একটি লক্ষ্য তৈরি করুন
- প্রকল্পের নির্ভরতা কল্পনা করুন
- প্রকল্পটিকে একাধিক লক্ষ্য এবং প্যাকেজে বিভক্ত করুন
- প্যাকেজ জুড়ে লক্ষ্য দৃশ্যমানতা নিয়ন্ত্রণ করুন
- রেফারেন্স লক্ষ্য লেবেল মাধ্যমে
- একটি লক্ষ্য স্থাপন
তুমি শুরু করার আগে
Bazel ইনস্টল করুন
টিউটোরিয়ালের জন্য প্রস্তুত করতে, প্রথমে Bazel ইনস্টল করুন যদি আপনার এটি ইতিমধ্যে ইনস্টল না থাকে।
JDK ইনস্টল করুন
- Java JDK ইনস্টল করুন (পছন্দের সংস্করণ 11, তবে 8 এবং 15 এর মধ্যে সংস্করণ সমর্থিত)। 
- JDK-এর দিকে নির্দেশ করতে JAVA_HOME এনভায়রনমেন্ট ভেরিয়েবল সেট করুন। - লিনাক্স/ম্যাকোসে: - export JAVA_HOME="$(dirname $(dirname $(realpath $(which javac))))"
- উইন্ডোজে: - কন্ট্রোল প্যানেল খুলুন।
- "সিস্টেম এবং নিরাপত্তা" > "সিস্টেম" > "উন্নত সিস্টেম সেটিংস" > "উন্নত" ট্যাবে যান > "পরিবেশ ভেরিয়েবল..."।
- "ব্যবহারকারী ভেরিয়েবল" তালিকার অধীনে (উপরে একটি), "নতুন..." ক্লিক করুন।
-  "ভেরিয়েবল নাম" ক্ষেত্রে, JAVA_HOMEলিখুন।
- "ব্রাউজ ডিরেক্টরি..." ক্লিক করুন।
-  JDK ডিরেক্টরিতে নেভিগেট করুন (উদাহরণস্বরূপ C:\Program Files\Java\jdk1.8.0_152)।
- সমস্ত ডায়ালগ উইন্ডোতে "ঠিক আছে" ক্লিক করুন।
 
 
নমুনা প্রকল্প পান
Bazel এর 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
└── WORKSPACE
বেজেল দিয়ে তৈরি করুন
ওয়ার্কস্পেস সেট আপ করুন
আপনি একটি প্রকল্প তৈরি করার আগে, আপনাকে তার কর্মক্ষেত্র সেট আপ করতে হবে। একটি ওয়ার্কস্পেস হল একটি ডিরেক্টরি যা আপনার প্রোজেক্টের সোর্স ফাইল এবং Bazel এর বিল্ড আউটপুট ধারণ করে। এটিতে এমন ফাইলও রয়েছে যা Bazel বিশেষ হিসাবে স্বীকৃতি দেয়:
- WORKSPACEফাইল, যা একটি Bazel ওয়ার্কস্পেস হিসাবে ডিরেক্টরি এবং এর বিষয়বস্তু সনাক্ত করে এবং প্রকল্পের ডিরেক্টরি কাঠামোর মূলে বাস করে,
- এক বা একাধিক - BUILDফাইল, যা Bazel কে বলে কিভাবে প্রকল্পের বিভিন্ন অংশ তৈরি করতে হয়। (ওয়ার্কস্পেসের মধ্যে একটি ডিরেক্টরি যেখানে একটি- BUILDফাইল রয়েছে একটি প্যাকেজ । আপনি এই টিউটোরিয়ালে পরে প্যাকেজ সম্পর্কে শিখবেন।)
 একটি Bazel ওয়ার্কস্পেস হিসাবে একটি ডিরেক্টরি মনোনীত করতে, সেই ডিরেক্টরিতে WORKSPACE নামে একটি খালি ফাইল তৈরি করুন।
যখন Bazel প্রকল্প তৈরি করে, সমস্ত ইনপুট এবং নির্ভরতা একই ওয়ার্কস্পেসে থাকতে হবে। বিভিন্ন ওয়ার্কস্পেসে থাকা ফাইলগুলি একে অপরের থেকে স্বাধীন যদি না লিঙ্ক করা হয়, যা এই টিউটোরিয়ালের সুযোগের বাইরে।
BUILD ফাইলটি বুঝুন
 একটি BUILD ফাইলে Bazel-এর জন্য বিভিন্ন ধরনের নির্দেশাবলী রয়েছে। সবচেয়ে গুরুত্বপূর্ণ প্রকার হল বিল্ড নিয়ম , যা ব্যাজেলকে বলে যে কীভাবে কাঙ্খিত আউটপুট তৈরি করতে হয়, যেমন এক্সিকিউটেবল বাইনারি বা লাইব্রেরি। BUILD ফাইলে একটি বিল্ড নিয়মের প্রতিটি উদাহরণকে একটি টার্গেট বলা হয় এবং সোর্স ফাইল এবং নির্ভরতার একটি নির্দিষ্ট সেট নির্দেশ করে। একটি লক্ষ্য অন্যান্য লক্ষ্যবস্তুর দিকেও নির্দেশ করতে পারে।
 java-tutorial/BUILD ফাইলটি দেখুন:
java_binary(
    name = "ProjectRunner",
    srcs = glob(["src/main/java/com/example/*.java"]),
)
 আমাদের উদাহরণে, ProjectRunner টার্গেট Bazel-এর অন্তর্নির্মিত java_binary ইনস্ট্যান্টিয়েট করে। নিয়মটি বেজেলকে একটি .jar ফাইল এবং একটি র্যাপার শেল স্ক্রিপ্ট তৈরি করতে বলে (উভয়টি লক্ষ্যের নামে নামকরণ করা হয়েছে)।
 লক্ষ্যের বৈশিষ্ট্যগুলি স্পষ্টভাবে এর নির্ভরতা এবং বিকল্পগুলিকে বর্ণনা করে৷ যদিও name বৈশিষ্ট্যটি বাধ্যতামূলক, অনেকগুলি ঐচ্ছিক। উদাহরণস্বরূপ, ProjectRunner নিয়ম লক্ষ্যে, name হল টার্গেটের নাম, srcs সোর্স ফাইলগুলি নির্দিষ্ট করে যা Bazel টার্গেট তৈরি করতে ব্যবহার করে এবং main_class সেই ক্লাসটি নির্দিষ্ট করে যেটিতে প্রধান পদ্ধতি রয়েছে। (আপনি হয়তো লক্ষ্য করেছেন যে আমাদের উদাহরণটি একের পর এক তালিকাবদ্ধ করার পরিবর্তে সোর্স ফাইলগুলির একটি সেট Bazel- এ পাস করার জন্য গ্লোব ব্যবহার করে।)
প্রকল্পটি তৈরি করুন
 আপনার নমুনা প্রকল্প তৈরি করতে, java-tutorial ডিরেক্টরিতে নেভিগেট করুন এবং চালান:
bazel build //:ProjectRunner
 টার্গেট লেবেলে, // অংশটি হল ওয়ার্কস্পেসের রুটের সাথে সম্পর্কিত BUILD ফাইলের অবস্থান (এই ক্ষেত্রে, রুট নিজেই), এবং ProjectRunner হল BUILD ফাইলের টার্গেট নাম। (এই টিউটোরিয়ালের শেষে আপনি আরও বিস্তারিতভাবে লক্ষ্য লেবেল সম্পর্কে শিখবেন।)
Bazel নিম্নলিখিত অনুরূপ আউটপুট উত্পাদন করে:
   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
 অভিনন্দন, আপনি এইমাত্র আপনার প্রথম Bazel টার্গেট তৈরি করেছেন! বেজেল স্থানগুলি কর্মক্ষেত্রের মূলে bazel-bin ডিরেক্টরিতে আউটপুট তৈরি করে। Bazel এর আউটপুট গঠন সম্পর্কে ধারণা পেতে এর বিষয়বস্তু ব্রাউজ করুন।
এখন আপনার সদ্য নির্মিত বাইনারি পরীক্ষা করুন:
bazel-bin/ProjectRunner
নির্ভরতা গ্রাফ পর্যালোচনা করুন
BUILD ফাইলগুলিতে স্পষ্টভাবে ঘোষণা করার জন্য Bazel-এর জন্য বিল্ড নির্ভরতা প্রয়োজন। Bazel প্রকল্পের নির্ভরতা গ্রাফ তৈরি করতে সেই বিবৃতিগুলি ব্যবহার করে, যা সঠিক বৃদ্ধিমূলক বিল্ডগুলিকে সক্ষম করে।
নমুনা প্রকল্পের নির্ভরতা কল্পনা করতে, আপনি ওয়ার্কস্পেস রুটে এই কমান্ডটি চালিয়ে নির্ভরতা গ্রাফের একটি পাঠ্য উপস্থাপনা তৈরি করতে পারেন:
bazel query  --notool_deps --noimplicit_deps "deps(//:ProjectRunner)" --output graph
 উপরের কমান্ডটি Bazel কে লক্ষ্য //:ProjectRunner (হোস্ট এবং অন্তর্নিহিত নির্ভরতা ব্যতীত) জন্য সমস্ত নির্ভরতা সন্ধান করতে এবং আউটপুটটিকে একটি গ্রাফ হিসাবে ফর্ম্যাট করতে বলে।
তারপর, গ্রাফভিজে পাঠ্যটি পেস্ট করুন।
আপনি দেখতে পাচ্ছেন, প্রকল্পটির একটি একক লক্ষ্য রয়েছে যা কোনও অতিরিক্ত নির্ভরতা ছাড়াই দুটি উত্স ফাইল তৈরি করে:
আপনি আপনার কর্মক্ষেত্র সেট আপ করার পরে, আপনার প্রকল্প তৈরি করুন এবং এর নির্ভরতা পরীক্ষা করুন, তারপর আপনি কিছু জটিলতা যোগ করতে পারেন।
আপনার Bazel বিল্ড পরিমার্জিত
ছোট প্রকল্পের জন্য একটি একক লক্ষ্য যথেষ্ট হলেও, আপনি দ্রুত বর্ধনশীল বিল্ডের জন্য (অর্থাৎ, শুধুমাত্র যা পরিবর্তন করা হয়েছে তা পুনর্নির্মাণের জন্য) এবং একটি প্রকল্পের একাধিক অংশ তৈরি করে আপনার বিল্ডগুলির গতি বাড়ানোর জন্য আপনি বড় প্রকল্পগুলিকে একাধিক লক্ষ্য এবং প্যাকেজে বিভক্ত করতে চাইতে পারেন। একবার.
একাধিক বিল্ড লক্ষ্য নির্দিষ্ট করুন
 আপনি নমুনা প্রকল্প বিল্ড দুটি লক্ষ্যে বিভক্ত করতে পারেন। নিম্নলিখিত দিয়ে 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"],
)
 এই কনফিগারেশনের সাথে, Bazel প্রথমে greeter লাইব্রেরি, তারপর ProjectRunner বাইনারি তৈরি করে। java_binary এ deps অ্যাট্রিবিউট Bazel কে বলে যে ProjectRunner বাইনারি তৈরি করতে greeter লাইব্রেরি প্রয়োজন।
প্রকল্পের এই নতুন সংস্করণটি তৈরি করতে, নিম্নলিখিত কমান্ডটি চালান:
bazel build //:ProjectRunner
Bazel নিম্নলিখিত অনুরূপ আউটপুট উত্পাদন করে:
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 পরিবর্তন করেন এবং প্রকল্পটি পুনর্নির্মাণ করেন, Bazel শুধুমাত্র সেই ফাইলটি পুনরায় কম্পাইল করে।
 নির্ভরতা গ্রাফের দিকে তাকিয়ে, আপনি দেখতে পাচ্ছেন যে ProjectRunner আগের মতো একই ইনপুটের উপর নির্ভর করে, কিন্তু বিল্ডের গঠন ভিন্ন: 
 আপনি এখন দুটি লক্ষ্য নিয়ে প্রকল্পটি তৈরি করেছেন। ProjectRunner টার্গেট দুটি সোর্স ফাইল তৈরি করে এবং অন্য একটি টার্গেট ( :greeter ) এর উপর নির্ভর করে, যা একটি অতিরিক্ত সোর্স ফাইল তৈরি করে।
একাধিক প্যাকেজ ব্যবহার করুন
 এখন প্রকল্পটিকে একাধিক প্যাকেজে বিভক্ত করা যাক। আপনি যদি src/main/java/com/example/cmdline ডিরেক্টরিটি দেখেন তবে আপনি দেখতে পাবেন যে এটিতে একটি BUILD ফাইল এবং কিছু উত্স ফাইলও রয়েছে। অতএব, Bazel-এ, ওয়ার্কস্পেসটিতে এখন দুটি প্যাকেজ রয়েছে, //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 অ্যাট্রিবিউটের মাধ্যমে জানে। নির্ভরতা গ্রাফটি দেখুন: 
 যাইহোক, বিল্ডটি সফল হওয়ার জন্য, আপনাকে অবশ্যই //src/main/java/com/example/cmdline/BUILD //BUILD visibility বৈশিষ্ট্য ব্যবহার করে লক্ষ্যে runner স্পষ্টভাবে দিতে হবে। এর কারণ হল ডিফল্টভাবে লক্ষ্যগুলি শুধুমাত্র একই BUILD ফাইলের অন্যান্য লক্ষ্যগুলির কাছে দৃশ্যমান। (পাবলিক API-এ ফাঁস হওয়া বাস্তবায়নের বিবরণ ধারণকারী লাইব্রেরিগুলির মতো সমস্যাগুলি প্রতিরোধ করতে ব্যাজেল লক্ষ্য দৃশ্যমানতা ব্যবহার করে।)
 এটি করার জন্য, java-tutorial/BUILD এ greeter টার্গেটে visibility অ্যাট্রিবিউট যোগ করুন নিচের মতো:
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
Bazel নিম্নলিখিত অনুরূপ আউটপুট উত্পাদন করে:
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 ফাইলে এবং কমান্ড লাইনে, Bazel টার্গেট লেবেল ব্যবহার করে টার্গেট উল্লেখ করতে - উদাহরণস্বরূপ, //: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/ //src/main/java/com/example/cmdline এর সম্পূর্ণ প্যাকেজ পাথ নির্দিষ্ট করতে হবে এবং আপনার টার্গেট লেবেল ছিল //src/main/java/com/example/cmdline:runner ।
স্থাপনার জন্য একটি জাভা লক্ষ্য প্যাকেজ করুন
চলুন এখন এর সমস্ত রানটাইম নির্ভরতা সহ বাইনারি তৈরি করে স্থাপনার জন্য একটি জাভা টার্গেট প্যাকেজ করি। এটি আপনাকে আপনার উন্নয়ন পরিবেশের বাইরে বাইনারি চালাতে দেয়।
 আপনার মনে আছে, java_binary বিল্ড নিয়ম একটি .jar এবং একটি wrapper শেল স্ক্রিপ্ট তৈরি করে। এই কমান্ডটি ব্যবহার করে 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.class এ runner.jar রয়েছে, কিন্তু এর নির্ভরতা নয়, Greeting.class । ব্যাজেল যে runner স্ক্রিপ্টটি তৈরি করে greeter.jar যোগ করে, তাই আপনি যদি এটিকে এভাবে ছেড়ে যান তবে এটি স্থানীয়ভাবে চলবে, কিন্তু এটি অন্য মেশিনে স্বতন্ত্রভাবে চলবে না। সৌভাগ্যবশত, java_binary নিয়ম আপনাকে একটি স্বয়ংসম্পূর্ণ, স্থাপনযোগ্য বাইনারি তৈরি করতে দেয়। এটি তৈরি করতে, টার্গেট নামের সাথে _deploy.jar যোগ করুন:
bazel build //src/main/java/com/example/cmdline:runner_deploy.jar
Bazel নিম্নলিখিত অনুরূপ আউটপুট উত্পাদন করে:
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 । 
- স্থানীয় এবং দূরবর্তী সংগ্রহস্থলগুলির সাথে কাজ করার বিষয়ে আরও জানতে বাহ্যিক নির্ভরতা । 
- Bazel সম্পর্কে আরো জানতে অন্যান্য নিয়ম . 
- Bazel এর সাথে C++ প্রজেক্ট তৈরি করা শুরু করার জন্য C++ বিল্ড টিউটোরিয়াল । 
- অ্যান্ড্রয়েড অ্যাপ্লিকেশন টিউটোরিয়াল এবং iOS অ্যাপ্লিকেশন টিউটোরিয়ালটি Bazel এর সাথে Android এবং iOS এর জন্য মোবাইল অ্যাপ্লিকেশন তৈরি করা শুরু করার জন্য। 
শুভ বিল্ডিং!