বেজেল টিউটোরিয়াল: একটি জাভা প্রকল্প তৈরি করুন

এই টিউটোরিয়ালটি Bazel-এর সাহায্যে জাভা অ্যাপ্লিকেশান তৈরির মূল বিষয়গুলি কভার করে৷ আপনি আপনার ওয়ার্কস্পেস সেট আপ করবেন এবং একটি সাধারণ জাভা প্রকল্প তৈরি করবেন যা মূল বেজেল ধারণাগুলি যেমন লক্ষ্য এবং BUILD ফাইলগুলিকে চিত্রিত করে।

আনুমানিক সমাপ্তির সময়: 30 মিনিট।

আপনি কি শিখবেন

এই টিউটোরিয়ালে আপনি শিখবেন কিভাবে:

  • একটি লক্ষ্য তৈরি করুন
  • প্রকল্পের নির্ভরতা কল্পনা করুন
  • প্রকল্পটিকে একাধিক লক্ষ্য এবং প্যাকেজে বিভক্ত করুন
  • প্যাকেজ জুড়ে লক্ষ্য দৃশ্যমানতা নিয়ন্ত্রণ করুন
  • রেফারেন্স লক্ষ্য লেবেল মাধ্যমে
  • একটি লক্ষ্য স্থাপন

তুমি শুরু করার আগে

Bazel ইনস্টল করুন

টিউটোরিয়ালের জন্য প্রস্তুত করতে, প্রথমে Bazel ইনস্টল করুন যদি আপনার এটি ইতিমধ্যে ইনস্টল না থাকে।

JDK ইনস্টল করুন

  1. Java JDK ইনস্টল করুন (পছন্দের সংস্করণ 11, তবে 8 এবং 15 এর মধ্যে সংস্করণ সমর্থিত)।

  2. JDK-এর দিকে নির্দেশ করতে JAVA_HOME এনভায়রনমেন্ট ভেরিয়েবল সেট করুন।

    • লিনাক্স/ম্যাকোসে:

      export JAVA_HOME="$(dirname $(dirname $(realpath $(which javac))))"
      
    • উইন্ডোজে:

      1. কন্ট্রোল প্যানেল খুলুন।
      2. "সিস্টেম এবং নিরাপত্তা" > "সিস্টেম" > "উন্নত সিস্টেম সেটিংস" > "উন্নত" ট্যাবে যান > "পরিবেশ ভেরিয়েবল..."।
      3. "ব্যবহারকারী ভেরিয়েবল" তালিকার অধীনে (উপরে একটি), "নতুন..." ক্লিক করুন।
      4. "ভেরিয়েবল নাম" ক্ষেত্রে, JAVA_HOME লিখুন।
      5. "ব্রাউজ ডিরেক্টরি..." ক্লিক করুন।
      6. JDK ডিরেক্টরিতে নেভিগেট করুন (উদাহরণস্বরূপ C:\Program Files\Java\jdk1.8.0_152 )।
      7. সমস্ত ডায়ালগ উইন্ডোতে "ঠিক আছে" ক্লিক করুন।

নমুনা প্রকল্প পান

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_binarydeps অ্যাট্রিবিউট 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/BUILDgreeter টার্গেটে 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.classrunner.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

আরও পড়া

আরো বিস্তারিত জানার জন্য, দেখুন:

শুভ বিল্ডিং!