Bazel টিউটোরিয়াল: একটি C++ প্রকল্প তৈরি করুন

ভূমিকা

Bazel নতুন? আপনি সঠিক জায়গায় আছেন. Bazel ব্যবহার করার একটি সরলীকৃত ভূমিকার জন্য এই ফার্স্ট বিল্ড টিউটোরিয়ালটি অনুসরণ করুন। এই টিউটোরিয়ালটি মূল পরিভাষাগুলিকে সংজ্ঞায়িত করে কারণ সেগুলি Bazel-এর প্রসঙ্গে ব্যবহৃত হয় এবং আপনাকে Bazel ওয়ার্কফ্লো-এর মূল বিষয়গুলির মধ্যে নিয়ে যায়৷ আপনার প্রয়োজনীয় সরঞ্জামগুলি দিয়ে শুরু করে, আপনি ক্রমবর্ধমান জটিলতার সাথে তিনটি প্রকল্প তৈরি এবং চালাবেন এবং কীভাবে এবং কেন সেগুলি আরও জটিল হয় তা শিখবেন।

যদিও Bazel হল একটি বিল্ড সিস্টেম যা মাল্টি-ল্যাঙ্গুয়েজ বিল্ডকে সমর্থন করে, এই টিউটোরিয়ালটি একটি উদাহরণ হিসাবে একটি C++ প্রকল্প ব্যবহার করে এবং সাধারণ নির্দেশিকা এবং প্রবাহ প্রদান করে যা বেশিরভাগ ভাষায় প্রযোজ্য।

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

পূর্বশর্ত

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

এরপরে, আপনার পছন্দের কমান্ড-লাইন টুলে নিম্নলিখিতটি চালিয়ে 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) ইনস্টল করে এবং এই টিউটোরিয়ালের জন্য সংগ্রহস্থল ক্লোন করে, আপনি Bazel এর সাথে আপনার প্রথম বিল্ডের ভিত্তি স্থাপন করেছেন। কিছু পদ সংজ্ঞায়িত করতে এবং আপনার কর্মক্ষেত্র সেট আপ করতে পরবর্তী বিভাগে চালিয়ে যান।

শুরু হচ্ছে

ওয়ার্কস্পেস সেট আপ করুন

আপনি একটি প্রকল্প তৈরি করার আগে, আপনাকে তার কর্মক্ষেত্র সেট আপ করতে হবে। একটি ওয়ার্কস্পেস হল একটি ডিরেক্টরি যা আপনার প্রোজেক্টের সোর্স ফাইল এবং Bazel এর বিল্ড আউটপুট ধারণ করে। এটিতে এই উল্লেখযোগ্য ফাইলগুলিও রয়েছে:

  • WORKSPACE file , যা একটি Bazel ওয়ার্কস্পেস হিসাবে ডিরেক্টরি এবং এর বিষয়বস্তু চিহ্নিত করে এবং প্রকল্পের ডিরেক্টরি কাঠামোর মূলে থাকে।
  • এক বা একাধিক BUILD files , যা Bazel কে বলে যে কিভাবে প্রকল্পের বিভিন্ন অংশ তৈরি করতে হয়। একটি BUILD ফাইল ধারণ করে কর্মক্ষেত্রের মধ্যে একটি ডিরেক্টরি হল একটি প্যাকেজ । (পরে এই টিউটোরিয়ালে প্যাকেজ সম্পর্কে আরও।)

ভবিষ্যতের প্রকল্পগুলিতে, একটি Bazel ওয়ার্কস্পেস হিসাবে একটি ডিরেক্টরিকে মনোনীত করতে, সেই ডিরেক্টরিতে WORKSPACE নামে একটি খালি ফাইল তৈরি করুন৷ এই টিউটোরিয়ালের উদ্দেশ্যে, একটি WORKSPACE ফাইল ইতিমধ্যেই প্রতিটি পর্যায়ে উপস্থিত রয়েছে।

দ্রষ্টব্য : যখন Bazel প্রকল্পটি তৈরি করে, তখন সমস্ত ইনপুট একই ওয়ার্কস্পেসে থাকতে হবে। বিভিন্ন ওয়ার্কস্পেসে থাকা ফাইলগুলি লিঙ্ক না করা পর্যন্ত একে অপরের থেকে স্বাধীন। ওয়ার্কস্পেস নিয়ম সম্পর্কে আরো বিস্তারিত তথ্য এই গাইডে পাওয়া যাবে।

BUILD ফাইলটি বুঝুন

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

cpp-tutorial/stage1/main ডিরেক্টরিতে BUILD ফাইলটি দেখুন:

cc_binary(
    name = "hello-world",
    srcs = ["hello-world.cc"],
)

আমাদের উদাহরণে, hello-world টার্গেট Bazel-এর অন্তর্নির্মিত cc_binary rule ইনস্ট্যান্টিয়েট করে। নিয়মটি বেজেলকে কোনো নির্ভরতা ছাড়াই hello-world.cc সোর্স ফাইল থেকে একটি স্বয়ংসম্পূর্ণ এক্সিকিউটেবল বাইনারি তৈরি করতে বলে।

সারমর্ম: শুরু হচ্ছে

এখন আপনি কিছু মূল পদের সাথে পরিচিত, এবং এই প্রকল্পের প্রসঙ্গে এবং সাধারণভাবে Bazel এর অর্থ কী। পরবর্তী বিভাগে, আপনি প্রকল্পের পর্যায় 1 তৈরি এবং পরীক্ষা করবেন।

পর্যায় 1: একক লক্ষ্য, একক প্যাকেজ

এটি প্রকল্পের প্রথম অংশ তৈরি করার সময়। একটি ভিজ্যুয়াল রেফারেন্সের জন্য, প্রকল্পের পর্যায় 1 বিভাগের কাঠামো হল:

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 ফাইলের টার্গেট নাম।

বেজেল এমন কিছু তৈরি করে যা দেখতে এইরকম:

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-bin ডিরেক্টরিতে আউটপুট তৈরি করে।

এখন আপনার সদ্য নির্মিত বাইনারি পরীক্ষা করুন, যা হল:

bazel-bin/main/hello-world

এটি একটি মুদ্রিত " Hello world " বার্তার ফলাফল।

এখানে পর্যায় 1 এর নির্ভরতা গ্রাফ:

Dependency graph for hello-world displays a single target with a single source file.

সারাংশ: পর্যায় 1

এখন যেহেতু আপনি আপনার প্রথম বিল্ডটি সম্পন্ন করেছেন, আপনার কাছে একটি প্রাথমিক ধারণা আছে কিভাবে একটি বিল্ড গঠন করা হয়। পরবর্তী পর্যায়ে, আপনি অন্য টার্গেট যোগ করে জটিলতা যোগ করবেন।

পর্যায় 2: একাধিক বিল্ড লক্ষ্য

ছোট প্রকল্পগুলির জন্য একটি একক লক্ষ্য যথেষ্ট হলেও, আপনি বড় প্রকল্পগুলিকে একাধিক লক্ষ্য এবং প্যাকেজে বিভক্ত করতে চাইতে পারেন। এটি দ্রুত ক্রমবর্ধমান বিল্ডগুলির জন্য অনুমতি দেয় - অর্থাৎ, Bazel শুধুমাত্র যা পরিবর্তিত হয়েছে তা পুনর্নির্মাণ করে - এবং একবারে একটি প্রকল্পের একাধিক অংশ তৈরি করে আপনার বিল্ডগুলির গতি বাড়ায়৷ টিউটোরিয়ালের এই পর্যায়ে একটি লক্ষ্য যোগ করে, এবং পরেরটি একটি প্যাকেজ যোগ করে।

স্টেজ 2 এর জন্য আপনি যে ডিরেক্টরিটির সাথে কাজ করছেন তা হল:

    ├──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 গ্রীট লাইব্রেরি তৈরি করে (বাজেলের অন্তর্নির্মিত cc_library rule ব্যবহার করে), তারপর hello-world বাইনারি। hello-world টার্গেটে ডিপস অ্যাট্রিবিউট deps বলে যে 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 শুধুমাত্র সেই ফাইলটি পুনরায় কম্পাইল করে।

নির্ভরতা গ্রাফের দিকে তাকিয়ে, আপনি দেখতে পাচ্ছেন যে হ্যালো-ওয়ার্ল্ড আগের মতো একই ইনপুটগুলির উপর নির্ভর করে, তবে বিল্ডের গঠন ভিন্ন:

Dependency graph for `hello-world` displays structure changes after modification to the file.

সারাংশ: পর্যায় 2

আপনি এখন দুটি লক্ষ্য নিয়ে প্রকল্পটি তৈরি করেছেন। hello-world টার্গেট একটি সোর্স ফাইল তৈরি করে এবং অন্য একটি টার্গেটের উপর নির্ভর করে ( //main:hello-greet ), যা দুটি অতিরিক্ত সোর্স ফাইল তৈরি করে। পরবর্তী বিভাগে, এটিকে এক ধাপ এগিয়ে নিয়ে যান এবং আরেকটি প্যাকেজ যোগ করুন।

পর্যায় 3: একাধিক প্যাকেজ

এই পরবর্তী পর্যায়ে জটিলতার আরেকটি স্তর যোগ করে এবং একাধিক প্যাকেজ সহ একটি প্রকল্প তৈরি করে। 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 অ্যাট্রিবিউটের মাধ্যমে জানে। আপনি এটি নির্ভরতা গ্রাফে প্রতিফলিত দেখতে পারেন:

Dependency graph for `hello-world` displays how the target in the main package depends on the target in the `lib` package.

বিল্ডটি সফল হওয়ার জন্য, আপনি দৃশ্যমানতা বৈশিষ্ট্য ব্যবহার করে lib/BUILD//lib:hello-time টার্গেটটিকে main/BUILD এর লক্ষ্যগুলির কাছে স্পষ্টভাবে দৃশ্যমান করুন। কারণ ডিফল্টভাবে লক্ষ্যমাত্রা শুধুমাত্র একই BUILD ফাইলের অন্যান্য লক্ষ্যমাত্রার কাছে দৃশ্যমান। Bazel লক্ষ্য দৃশ্যমানতা ব্যবহার করে সমস্যাগুলি প্রতিরোধ করতে যেমন লাইব্রেরিগুলির বাস্তবায়নের বিবরণ পাবলিক APIগুলিতে ফাঁস হওয়া।

এখন প্রকল্পের এই চূড়ান্ত সংস্করণটি তৈরি করুন। চালানোর মাধ্যমে cpp-tutorial/stage3 ডিরেক্টরিতে স্যুইচ করুন:

cd  ../stage3

আবার, নিম্নলিখিত কমান্ড চালান:

bazel build //main:hello-world

বেজেল এমন কিছু তৈরি করে যা দেখতে এইরকম:

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

সারাংশ: পর্যায় 3

আপনি এখন তিনটি লক্ষ্য সহ দুটি প্যাকেজ হিসাবে প্রকল্পটি তৈরি করেছেন এবং তাদের মধ্যে নির্ভরতা বুঝতে পেরেছেন, যা আপনাকে এগিয়ে যেতে এবং Bazel এর সাথে ভবিষ্যতের প্রকল্পগুলি তৈরি করতে সজ্জিত করে। পরবর্তী বিভাগে, কিভাবে আপনার Bazel যাত্রা চালিয়ে যেতে হয় তা দেখুন।

পরবর্তী পদক্ষেপ

আপনি এখন Bazel এর সাথে আপনার প্রথম মৌলিক বিল্ড সম্পূর্ণ করেছেন, কিন্তু এটি শুধুমাত্র শুরু। Bazel এর সাথে শেখা চালিয়ে যাওয়ার জন্য এখানে আরও কিছু সংস্থান রয়েছে:

শুভ বিল্ডিং!