এই টিউটোরিয়ালটি একটি প্রকল্পের জন্য কিভাবে 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/BUILDtoolchain/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/BUILDBUILD-এ একটি লোড স্টেটমেন্ট যোগ করুন: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++ টুলচেন কনফিগারেশন দেখুন