এই টিউটোরিয়ালটি একটি প্রকল্পের জন্য কিভাবে C++ টুলচেইন কনফিগার করতে হয় তা বর্ণনা করার জন্য একটি উদাহরণের দৃশ্য ব্যবহার করে। এটি একটি উদাহরণ C++ প্রকল্পের উপর ভিত্তি করে যা clang
ব্যবহার করে ত্রুটি-মুক্ত তৈরি করে।
আপনি কি শিখবেন
এই টিউটোরিয়ালে আপনি শিখবেন কিভাবে:
- বিল্ড পরিবেশ সেট আপ করুন
- C++ টুলচেইন কনফিগার করুন
- একটি স্টারলার্ক নিয়ম তৈরি করুন যা
cc_toolchain
এর জন্য অতিরিক্ত কনফিগারেশন প্রদান করে যাতে Bazelclang
সহ অ্যাপ্লিকেশনটি তৈরি করতে পারে - একটি লিনাক্স মেশিনে
bazel build --config=clang_config //main:hello-world
চালিয়ে প্রত্যাশিত ফলাফল নিশ্চিত করুন - C++ অ্যাপ্লিকেশন তৈরি করুন
তুমি শুরু করার আগে
বিল্ড পরিবেশ সেট আপ করুন
এই টিউটোরিয়ালটি ধরে নেয় আপনি লিনাক্সে আছেন এবং সফলভাবে C++ অ্যাপ্লিকেশন তৈরি করেছেন এবং উপযুক্ত টুলিং এবং লাইব্রেরি ইনস্টল করেছেন। টিউটোরিয়ালটিতে clang version 9.0.1
ব্যবহার করা হয়েছে, যা আপনি আপনার সিস্টেমে ইনস্টল করতে পারেন।
নিম্নলিখিত হিসাবে আপনার বিল্ড পরিবেশ সেট আপ করুন:
আপনি যদি ইতিমধ্যে এটি না করে থাকেন তবে Bazel 0.23 বা তার পরে ডাউনলোড এবং ইনস্টল করুন ৷
GitHub থেকে উদাহরণ C++ প্রকল্পটি ডাউনলোড করুন এবং আপনার স্থানীয় মেশিনে একটি খালি ডিরেক্টরিতে রাখুন।
main/BUILD
ফাইলে নিম্নলিখিতcc_binary
টার্গেট যোগ করুন:cc_binary( name = "hello-world", srcs = ["hello-world.cc"], )
--config
পতাকা ব্যবহার করতে নিম্নলিখিত বিষয়বস্তু সহ ওয়ার্কস্পেস ডিরেক্টরির মূলে একটি.bazelrc
ফাইল তৈরি করুন:# Use our custom-configured c++ toolchain. build:clang_config --crosstool_top=//toolchain:clang_suite # Use --cpu as a differentiator. build:clang_config --cpu=k8 # Use the default Bazel C++ toolchain to build the tools used during the # build. build:clang_config --host_crosstool_top=@bazel_tools//tools/cpp:toolchain
একটি এন্ট্রি build:{config_name} --flag=value
, কমান্ড লাইন পতাকা --config={config_name}
সেই নির্দিষ্ট পতাকার সাথে যুক্ত। ব্যবহৃত পতাকার ডকুমেন্টেশন দেখুন: crosstool_top
, cpu
এবং host_crosstool_top
।
যখন আপনি bazel build --config=clang_config //main:hello-world
দিয়ে আপনার টার্গেট তৈরি করেন, তখন Bazel cc_toolchain_suite //toolchain:clang_suite
থেকে আপনার কাস্টম টুলচেন ব্যবহার করে। স্যুটটি বিভিন্ন CPU-র জন্য বিভিন্ন টুলচেন তালিকাভুক্ত করতে পারে, এবং সেই কারণেই এটি পতাকা --cpu=k8
দিয়ে আলাদা করা হয়েছে।
যেহেতু Bazel নির্মাণের সময় C++ এ লেখা অনেক অভ্যন্তরীণ টুল ব্যবহার করে, যেমন প্রসেস-র্যাপার, পূর্বে বিদ্যমান ডিফল্ট C++ টুলচেন হোস্ট প্ল্যাটফর্মের জন্য নির্দিষ্ট করা হয়েছে, যাতে এই টুলগুলি এই টিউটোরিয়ালে তৈরি করা একটির পরিবর্তে সেই টুলচেন ব্যবহার করে তৈরি করা হয়। .
C++ টুলচেইন কনফিগার করা হচ্ছে
C++ টুলচেন কনফিগার করতে, বারবার অ্যাপ্লিকেশন তৈরি করুন এবং নীচে বর্ণিত হিসাবে প্রতিটি ত্রুটি একে একে দূর করুন।
নিম্নলিখিত কমান্ড দিয়ে বিল্ড চালান:
bazel build --config=clang_config //main:hello-world
কারণ আপনি
.bazelrc
ফাইলে--crosstool_top=//toolchain:clang_suite
উল্লেখ করেছেন, Bazel নিম্নলিখিত ত্রুটিটি ছুঁড়েছে:No such package `toolchain`: BUILD file not found on package path.
ওয়ার্কস্পেস ডিরেক্টরিতে, প্যাকেজের জন্য
toolchain
ডিরেক্টরি এবংtoolchain
ডিরেক্টরির ভিতরে একটি খালিBUILD
ফাইল তৈরি করুন।আবার বিল্ড চালান. যেহেতু
toolchain
প্যাকেজ এখনওclang_suite
সংজ্ঞায়িত করে না, Bazel নিম্নলিখিত ত্রুটিটি নিক্ষেপ করে:No such target '//toolchain:clang_suite': target 'clang_suite' not declared in package 'toolchain' defined by .../toolchain/BUILD
toolchain/BUILD
ফাইলে, একটি খালি ফাইলগ্রুপ নিম্নরূপ সংজ্ঞায়িত করুন:package(default_visibility = ["//visibility:public"]) filegroup(name = "clang_suite")
আবার বিল্ড চালান. Bazel নিম্নলিখিত ত্রুটি নিক্ষেপ করে:
'//toolchain:clang_suite' does not have mandatory providers: 'ToolchainInfo'
Bazel আবিষ্কার করেছে যে
--crosstool_top
পতাকা একটি নিয়ম নির্দেশ করে যা প্রয়োজনীয়ToolchainInfo
প্রদানকারী প্রদান করে না। তাই আপনাকে--crosstool_top
একটি নিয়মের দিকে নির্দেশ করতে হবে যাToolchainInfo
প্রদান করে - সেটি হলcc_toolchain_suite
নিয়ম।toolchain/BUILD
ফাইলে, খালি ফাইলগ্রুপটিকে নিম্নলিখিতগুলির সাথে প্রতিস্থাপন করুন:cc_toolchain_suite( name = "clang_suite", toolchains = { "k8": ":k8_toolchain", }, )
toolchains
অ্যাট্রিবিউট স্বয়ংক্রিয়ভাবে--cpu
(এবং--compiler
নির্দিষ্ট করা হলে) মানগুলিকেcc_toolchain
এ মানচিত্র তৈরি করে। আপনি এখনও কোনোcc_toolchain
লক্ষ্য নির্ধারণ করেননি এবং Bazel শীঘ্রই এটি সম্পর্কে অভিযোগ করবে।আবার বিল্ড চালান. Bazel নিম্নলিখিত ত্রুটি নিক্ষেপ করে:
Rule '//toolchain:k8_toolchain' does not exist
এখন আপনাকে
cc_toolchain_suite.toolchains
অ্যাট্রিবিউটের প্রতিটি মানের জন্যcc_toolchain
লক্ষ্য নির্ধারণ করতে হবে।toolchain/BUILD
ফাইলে নিম্নলিখিত যোগ করুন:filegroup(name = "empty") cc_toolchain( name = "k8_toolchain", toolchain_identifier = "k8-toolchain", toolchain_config = ":k8_toolchain_config", all_files = ":empty", compiler_files = ":empty", dwp_files = ":empty", linker_files = ":empty", objcopy_files = ":empty", strip_files = ":empty", supports_param_files = 0, )
আবার বিল্ড চালান. Bazel নিম্নলিখিত ত্রুটি নিক্ষেপ করে:
Rule '//toolchain:k8_toolchain_config' does not exist
এরপরে,
toolchain/BUILD
ফাইলে একটি ":k8_toolchain_config" টার্গেট যোগ করুন:filegroup(name = "k8_toolchain_config")
আবার বিল্ড চালান. Bazel নিম্নলিখিত ত্রুটি নিক্ষেপ করে:
'//toolchain:k8_toolchain_config' does not have mandatory providers: 'CcToolchainConfigInfo'
CcToolchainConfigInfo
হল একটি প্রদানকারী যা আপনি আপনার C++ টুলচেইন কনফিগার করতে ব্যবহার করেন। এই ত্রুটিটি ঠিক করতে, একটি স্টারলার্ক নিয়ম তৈরি করুন যা নিম্নোক্ত বিষয়বস্তু সহ একটিtoolchain/cc_toolchain_config.bzl
ফাইল তৈরি করে Bazel কেCcToolchainConfigInfo
প্রদান করে:def _impl(ctx): return cc_common.create_cc_toolchain_config_info( ctx = ctx, toolchain_identifier = "k8-toolchain", host_system_name = "local", target_system_name = "local", target_cpu = "k8", target_libc = "unknown", compiler = "clang", abi_version = "unknown", abi_libc_version = "unknown", ) cc_toolchain_config = rule( implementation = _impl, attrs = {}, provides = [CcToolchainConfigInfo], )
cc_common.create_cc_toolchain_config_info()
প্রয়োজনীয় প্রদানকারীCcToolchainConfigInfo
তৈরি করে।cc_toolchain_config
নিয়মটি ব্যবহার করতে,toolchains/BUILD
BUILD-এ একটি লোড স্টেটমেন্ট যোগ করুন:load(":cc_toolchain_config.bzl", "cc_toolchain_config")
এবং "k8_toolchain_config" ফাইলগ্রুপটিকে একটি
cc_toolchain_config
নিয়মের ঘোষণা দিয়ে প্রতিস্থাপন করুন:cc_toolchain_config(name = "k8_toolchain_config")
আবার বিল্ড চালান. Bazel নিম্নলিখিত ত্রুটি নিক্ষেপ করে:
.../BUILD:1:1: C++ compilation of rule '//:hello-world' failed (Exit 1) src/main/tools/linux-sandbox-pid1.cc:421: "execvp(toolchain/DUMMY_GCC_TOOL, 0x11f20e0)": No such file or directory Target //:hello-world failed to build`
এই মুহুর্তে, ব্যাজেলের কাছে কোড তৈরি করার চেষ্টা করার জন্য পর্যাপ্ত তথ্য রয়েছে তবে প্রয়োজনীয় বিল্ড ক্রিয়াগুলি সম্পূর্ণ করতে কী সরঞ্জামগুলি ব্যবহার করতে হবে তা এখনও জানে না। ব্যাজেলকে কোন সরঞ্জামগুলি ব্যবহার করতে হবে তা জানাতে আপনি স্টারলার্ক নিয়ম বাস্তবায়ন সংশোধন করবেন। এর জন্য, আপনার
@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl
থেকে tool_path() কনস্ট্রাক্টর প্রয়োজন:# toolchain/cc_toolchain_config.bzl: # NEW load("@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl", "tool_path") def _impl(ctx): tool_paths = [ # NEW tool_path( name = "gcc", path = "/usr/bin/clang", ), tool_path( name = "ld", path = "/usr/bin/ld", ), tool_path( name = "ar", path = "/usr/bin/ar", ), tool_path( name = "cpp", path = "/bin/false", ), tool_path( name = "gcov", path = "/bin/false", ), tool_path( name = "nm", path = "/bin/false", ), tool_path( name = "objdump", path = "/bin/false", ), tool_path( name = "strip", path = "/bin/false", ), ] return cc_common.create_cc_toolchain_config_info( ctx = ctx, toolchain_identifier = "local", host_system_name = "local", target_system_name = "local", target_cpu = "k8", target_libc = "unknown", compiler = "clang", abi_version = "unknown", abi_libc_version = "unknown", tool_paths = tool_paths, # NEW )
নিশ্চিত করুন যে
/usr/bin/clang
এবং/usr/bin/ld
আপনার সিস্টেমের জন্য সঠিক পথ।আবার বিল্ড চালান. Bazel নিম্নলিখিত ত্রুটি নিক্ষেপ করে:
..../BUILD:3:1: undeclared inclusion(s) in rule '//main:hello-world': this rule is missing dependency declarations for the following files included by 'main/hello-world.cc': '/usr/include/c++/9/ctime' '/usr/include/x86_64-linux-gnu/c++/9/bits/c++config.h' '/usr/include/x86_64-linux-gnu/c++/9/bits/os_defines.h' ....
Bazel জানতে হবে যেখানে অন্তর্ভুক্ত শিরোনাম অনুসন্ধান করতে হবে। এটি সমাধান করার একাধিক উপায় রয়েছে, যেমন
cc_binary
এরincludes
বৈশিষ্ট্য ব্যবহার করা, কিন্তু এখানে এটিcc_common.create_cc_toolchain_config_info
এরcxx_builtin_include_directories
প্যারামিটারের সাহায্যে টুলচেইন স্তরে সমাধান করা হয়েছে। সতর্ক থাকুন যে আপনি যদিclang
এর একটি ভিন্ন সংস্করণ ব্যবহার করেন, তাহলে অন্তর্ভুক্ত পথটি ভিন্ন হবে। এই পথগুলি বিতরণের উপর নির্ভর করে ভিন্ন হতে পারে।এই মত দেখতে
toolchain/cc_toolchain_config.bzl
এ রিটার্ন মান পরিবর্তন করুন:return cc_common.create_cc_toolchain_config_info( ctx = ctx, cxx_builtin_include_directories = [ # NEW "/usr/lib/llvm-9/lib/clang/9.0.1/include", "/usr/include", ], toolchain_identifier = "local", host_system_name = "local", target_system_name = "local", target_cpu = "k8", target_libc = "unknown", compiler = "clang", abi_version = "unknown", abi_libc_version = "unknown", tool_paths = tool_paths, )
বিল্ড কমান্ডটি আবার চালান, আপনি একটি ত্রুটি দেখতে পাবেন:
/usr/bin/ld: bazel-out/k8-fastbuild/bin/main/_objs/hello-world/hello-world.o: in function `print_localtime()': hello-world.cc:(.text+0x68): undefined reference to `std::cout'
এর কারণ হল লিঙ্কারটি C++ স্ট্যান্ডার্ড লাইব্রেরি অনুপস্থিত এবং এটি তার চিহ্নগুলি খুঁজে পাচ্ছে না। এটি সমাধান করার অনেক উপায় আছে, যেমন
cc_binary
এরlinkopts
অ্যাট্রিবিউট ব্যবহার করা। এখানে এটি নিশ্চিত করে সমাধান করা হয়েছে যে টুলচেন ব্যবহার করে কোনো লক্ষ্যকে এই পতাকাটি নির্দিষ্ট করতে হবে না।cc_toolchain_config.bzl
এ নিম্নলিখিত কোডটি অনুলিপি করুন:# NEW load("@bazel_tools//tools/build_defs/cc:action_names.bzl", "ACTION_NAMES") # NEW load( "@bazel_tools//tools/cpp:cc_toolchain_config_lib.bzl", "feature", "flag_group", "flag_set", "tool_path", ) all_link_actions = [ # NEW ACTION_NAMES.cpp_link_executable, ACTION_NAMES.cpp_link_dynamic_library, ACTION_NAMES.cpp_link_nodeps_dynamic_library, ] def _impl(ctx): tool_paths = [ tool_path( name = "gcc", path = "/usr/bin/clang", ), tool_path( name = "ld", path = "/usr/bin/ld", ), tool_path( name = "ar", path = "/bin/false", ), tool_path( name = "cpp", path = "/bin/false", ), tool_path( name = "gcov", path = "/bin/false", ), tool_path( name = "nm", path = "/bin/false", ), tool_path( name = "objdump", path = "/bin/false", ), tool_path( name = "strip", path = "/bin/false", ), ] features = [ # NEW feature( name = "default_linker_flags", enabled = True, flag_sets = [ flag_set( actions = all_link_actions, flag_groups = ([ flag_group( flags = [ "-lstdc++", ], ), ]), ), ], ), ] return cc_common.create_cc_toolchain_config_info( ctx = ctx, features = features, # NEW cxx_builtin_include_directories = [ "/usr/lib/llvm-9/lib/clang/9.0.1/include", "/usr/include", ], toolchain_identifier = "local", host_system_name = "local", target_system_name = "local", target_cpu = "k8", target_libc = "unknown", compiler = "clang", abi_version = "unknown", abi_libc_version = "unknown", tool_paths = tool_paths, ) cc_toolchain_config = rule( implementation = _impl, attrs = {}, provides = [CcToolchainConfigInfo], )
আপনি যদি
bazel build --config=clang_config //main:hello-world
, এটি অবশেষে তৈরি করা উচিত।
আপনার কাজ পর্যালোচনা করুন
এই টিউটোরিয়ালে আপনি শিখেছেন কিভাবে একটি বেসিক C++ টুলচেন কনফিগার করতে হয়, কিন্তু টুলচেন এই সাধারণ উদাহরণের চেয়ে বেশি শক্তিশালী।
মূল উপায়গুলি হল: - আপনাকে কমান্ড লাইনে একটি --crosstool_top
পতাকা নির্দিষ্ট করতে হবে যা একটি cc_toolchain_suite
এর দিকে নির্দেশ করবে - আপনি .bazelrc
ফাইল ব্যবহার করে একটি নির্দিষ্ট কনফিগারেশনের জন্য একটি শর্টকাট তৈরি করতে পারেন - cc_toolchain_suite বিভিন্ন জন্য cc_toolchains
তালিকাভুক্ত করতে পারে সিপিইউ এবং কম্পাইলার। আপনি কমান্ড লাইন পতাকা ব্যবহার করতে পারেন যেমন --cpu
পার্থক্য করতে। - আপনাকে টুলচেইনকে জানাতে হবে যে টুলগুলো কোথায় থাকে। এই টিউটোরিয়ালে একটি সরলীকৃত সংস্করণ রয়েছে যেখানে আপনি সিস্টেম থেকে সরঞ্জামগুলি অ্যাক্সেস করতে পারবেন। আপনি যদি আরও স্বয়ংসম্পূর্ণ পদ্ধতিতে আগ্রহী হন, আপনি এখানে কর্মক্ষেত্র সম্পর্কে পড়তে পারেন। আপনার টুলগুলি একটি ভিন্ন ওয়ার্কস্পেস থেকে আসতে পারে এবং আপনাকে তাদের ফাইলগুলিকে cc_toolchain
এ অ্যাট্রিবিউটের উপর লক্ষ্য নির্ভরতা সহ উপলব্ধ করতে হবে, যেমন compiler_files
। tool_paths
পরিবর্তন করা দরকার। - বিভিন্ন অ্যাকশনে কোন ফ্ল্যাগগুলি পাস করা উচিত তা কাস্টমাইজ করার জন্য আপনি বৈশিষ্ট্যগুলি তৈরি করতে পারেন, এটি লিঙ্কিং বা অন্য কোনও ধরণের অ্যাকশন হোক।
আরও পড়া
আরো বিস্তারিত জানার জন্য, C++ টুলচেন কনফিগারেশন দেখুন