C++ टूलचेन कॉन्फ़िगरेशन

खास जानकारी

सही विकल्पों के साथ कंपाइलर को शुरू करने के लिए, Bazel को कंपाइलर के इंटरनल के बारे में कुछ जानकारी चाहिए, जैसे कि डायरेक्ट्री और ज़रूरी फ़्लैग शामिल करना. दूसरे शब्दों में कहें, तो कंपाइलर के काम करने के तरीके को समझने के लिए, Bazel को कंपाइलर के आसान मॉडल की ज़रूरत होगी.

Bazel के लिए यह जानना ज़रूरी है:

  • कंपाइलर, थिनएलटीओ, मॉड्यूल, डाइनैमिक लिंकिंग या पीआईसी (रैंक इंडिपेंडेंट कोड) के साथ काम करता है या नहीं.
  • gcc, ld, ar, objcopy वगैरह जैसे ज़रूरी टूल के लिए पाथ.
  • बिल्ट-इन सिस्टम में डायरेक्ट्री शामिल होती हैं. Bazel को इनकी पुष्टि करनी होगी कि सोर्स फ़ाइल में शामिल सभी हेडर की जानकारी BUILD फ़ाइल में सही तरीके से दी गई थी.
  • डिफ़ॉल्ट sysroot.
  • कंपाइल करने, लिंक करने, और संग्रहित करने के लिए किन फ़्लैग का इस्तेमाल करना है.
  • साथ काम करने वाले कंपाइलेशन मोड के लिए कौनसे फ़्लैग इस्तेमाल करने हैं (opt, dbg, Fastbuild).
  • कंपाइलर के लिए खास तौर पर ज़रूरी वैरिएबल बनाएं.

अगर कंपाइलर एक से ज़्यादा आर्किटेक्चर के साथ काम करता है, तो Bazel को उन्हें अलग-अलग कॉन्फ़िगर करना होगा.

CcToolchainConfigInfo ऐसी कंपनी है जो Bazel के C++ नियमों के व्यवहार को कॉन्फ़िगर करने के लिए, ज़रूरी लेवल की जानकारी देती है. डिफ़ॉल्ट रूप से, Bazel आपके बिल्ड के लिए CcToolchainConfigInfo को अपने-आप कॉन्फ़िगर करता है. हालांकि, आपके पास इसे मैन्युअल तरीके से कॉन्फ़िगर करने का विकल्प होता है. इसके लिए, आपको स्टारलार्क नियम की ज़रूरत होगी, जो CcToolchainConfigInfo देता हो. साथ ही, आपको अपने नियम पर cc_toolchain के toolchain_config एट्रिब्यूट की जानकारी देनी होगी. cc_common.create_cc_toolchain_config_info() पर कॉल करके, CcToolchainConfigInfo बनाया जा सकता है. @rules_cc//cc:cc_toolchain_config_lib.bzl में आपको ऐसे सभी निर्देशों के लिए Starlark कंस्ट्रक्टर मिल सकते हैं जिनकी इस प्रोसेस के लिए ज़रूरत होगी.

जब C++ टारगेट, विश्लेषण के चरण में जाता है, तो Bazel BUILD फ़ाइल के आधार पर सही cc_toolchain टारगेट चुनता है औरcc_toolchain.toolchain_config एट्रिब्यूट में बताए गए टारगेट से, CcToolchainConfigInfo की सेवा देने वाली कंपनी देता है. cc_toolchain टारगेट इस जानकारी को CcToolchainProvider के ज़रिए C++ टारगेट को पास करता है.

उदाहरण के लिए, cc_binary या cc_library जैसे नियम से इंस्टैंशिएट किए जाने वाले, कंपाइल या लिंक करने के लिए यह जानकारी ज़रूरी है:

  • इस्तेमाल करने के लिए कंपाइलर या लिंकर
  • कंपाइलर/लिंकर के लिए कमांड-लाइन फ़्लैग
  • कॉन्फ़िगरेशन फ़्लैग, --copt/--linkopt विकल्पों से पास किए गए
  • एनवायरमेंट वैरिएबल
  • सैंडबॉक्स में कार्रवाई करने के लिए ज़रूरी आर्टफ़ैक्ट

सैंडबॉक्स में ज़रूरी आर्टफ़ैक्ट को छोड़कर, ऊपर दी गई सभी जानकारी Starlark टारगेट में तय की गई है. यह जानकारी, cc_toolchain के टारगेट में दी गई है.

सैंडबॉक्स में शिप किए जाने वाले आर्टफ़ैक्ट का एलान, cc_toolchain टारगेट में किया जाता है. उदाहरण के लिए, cc_toolchain.linker_files एट्रिब्यूट की मदद से, लिंकर बाइनरी और टूलचेन लाइब्रेरी के बारे में यह बताया जा सकता है कि किन लाइब्रेरी को सैंडबॉक्स में भेजना है.

टूलचेन चुनना

टूलचेन चुनने का लॉजिक इस तरह काम करता है:

  1. उपयोगकर्ता, BUILD फ़ाइल में cc_toolchain_suite टारगेट के बारे में बताता है और --crosstool_top विकल्प का इस्तेमाल करके, बैजल को टारगेट पर पॉइंट करता है.

  2. cc_toolchain_suite टारगेट में कई टूलचेन का रेफ़रंस दिया गया है. --cpu और --compiler फ़्लैग की वैल्यू से यह तय होता है कि इनमें से कौनसे टूलचेन चुने गए हैं. यह या तो सिर्फ़ --cpu फ़्लैग की वैल्यू के आधार पर या --cpu | --compiler की संयुक्त वैल्यू के आधार पर चुना जाता है. चुनने की प्रोसेस यहां दी गई है:

    • अगर --compiler विकल्प दिया गया है, तो Bazel, cc_toolchain_suite.toolchains एट्रिब्यूट से --cpu | --compiler वाली एंट्री को चुनता है. अगर Bazel को उससे जुड़ी एंट्री नहीं मिलती है, तो यह एक गड़बड़ी दिखाता है.

    • अगर --compiler विकल्प नहीं दिया गया है, तो Bazel, cc_toolchain_suite.toolchains एट्रिब्यूट से सिर्फ़ --cpu चुनकर, इससे जुड़ी एंट्री को चुनता है.

    • अगर कोई फ़्लैग तय नहीं किया गया है, तो Bazel, होस्ट सिस्टम की जांच करता है और अपनी जांच में मिली जानकारी के हिसाब से, --cpu की वैल्यू चुनता है. जांच करने के तरीके का कोड देखें.

टूलचेन चुने जाने के बाद, Starlark नियम में उससे जुड़े feature और action_config ऑब्जेक्ट, बिल्ड के कॉन्फ़िगरेशन को कंट्रोल करते हैं. जैसे, बाद में बताए गए आइटम. इन मैसेज की मदद से, Bazel बाइनरी में बदलाव किए बिना, Bazel में पूरी तरह से सभी C++ सुविधाएं लागू कर दी जा सकती हैं. C++ नियम कई यूनीक कार्रवाइयों के साथ काम करते हैं. इन कार्रवाइयों के बारे में, Bzel के सोर्स कोड में विस्तार से बताया गया है.

सुविधाएं

सुविधा एक ऐसी इकाई है जिसके लिए कमांड-लाइन फ़्लैग, कार्रवाइयां, एक्ज़ीक्यूशन एनवायरमेंट पर पाबंदियां या डिपेंडेंसी में बदलाव करना ज़रूरी होता है. कोई सुविधा बहुत आसान हो सकती है, जैसे कि BUILD फ़ाइल को फ़्लैग के कॉन्फ़िगरेशन चुनने की अनुमति देना, जैसे कि treat_warnings_as_errors या C++ नियमों को इस्तेमाल करने के साथ-साथ, कंपाइलेशन में नई कार्रवाइयां और इनपुट शामिल करें, जैसे कि header_modules या thin_lto.

आम तौर पर, CcToolchainConfigInfo में सुविधाओं की एक सूची होती है. हर सुविधा में एक या उससे ज़्यादा फ़्लैग ग्रुप होते हैं. हर सुविधा में Bazel की खास कार्रवाइयों पर लागू होने वाले फ़्लैग की एक सूची होती है.

एक सुविधा को नाम दिया जाता है जिससे Bazel रिलीज़ से, Starlark नियम के कॉन्फ़िगरेशन को पूरी तरह से अलग किया जा सकता है. दूसरे शब्दों में कहें, तो जब तक Bazel रिलीज़, CcToolchainConfigInfo कॉन्फ़िगरेशन के काम करने के तरीके पर असर नहीं डालता, तब तक उस कॉन्फ़िगरेशन पर नई सुविधाओं के इस्तेमाल की ज़रूरत नहीं पड़ती.

सुविधा को इनमें से किसी एक तरीके से चालू किया जाता है:

  • सुविधा का enabled फ़ील्ड true पर सेट है.
  • Bazel या नियम का मालिक साफ़ तौर पर इसे चालू करता है.
  • उपयोगकर्ता इसे --feature Bazel विकल्प या features नियम एट्रिब्यूट के ज़रिए चालू करता है.

ये सुविधाएं एक-दूसरे पर निर्भर कर सकती हैं. ये कमांड लाइन फ़्लैग, BUILD फ़ाइल सेटिंग, और दूसरे वैरिएबल पर निर्भर करती हैं.

सुविधा से जुड़ी मेट्रिक

आम तौर पर, डिपेंडेंसी को सीधे Bazel के साथ मैनेज किया जाता है. यह सिर्फ़ ज़रूरी शर्तों को लागू करता है. साथ ही, बिल्ड में बताई गई सुविधाओं के बीच टकराव को मैनेज करता है. टूलचेन स्पेसिफ़िकेशन की मदद से, सीधे तौर पर Starlark नियम में इस्तेमाल के लिए विस्तृत सीमाएं तय की जा सकती हैं. यह सुविधा, सुविधा और एक्सपैंशन को कंट्रोल करती है. इनके उदाहरण हैं:

सीमा Description
requires = [
   feature_set (features = [
       'feature-name-1',
       'feature-name-2'
   ]),
]
सुविधा के लेवल पर. यह सुविधा सिर्फ़ तब काम करती है, जब बताई गई ज़रूरी सुविधाएं चालू हों. उदाहरण के लिए, जब कोई सुविधा सिर्फ़ कुछ बिल्ड मोड (opt, dbg या fastbuild) में काम करती है. अगर `ज़रूरी है` में एक से ज़्यादा `feature_set`शामिल हों, तो यह सुविधा तब काम करती है, जब `feature_set`में से कोई एक काम करता हो (जब बताई गई सभी सुविधाएं चालू हों).
implies = ['feature']

सुविधा के लेवल पर. यह सुविधा, बताई गई सुविधा(सुविधाओं) का प्रतिनिधित्व करती है. किसी सुविधा को चालू करने पर, उसमें शामिल सभी सुविधाएं साफ़ तौर पर चालू हो जाती हैं. इसका मतलब है कि यह सुविधा बार-बार काम करती है.

साथ ही, सुविधाओं के किसी सेट में से सामान्य सुविधाओं के काम करने के तरीके को शामिल करने की सुविधा भी मिलती है. जैसे, सैनिटाइज़र के सामान्य हिस्से. शामिल सुविधाएं बंद नहीं की जा सकतीं.

provides = ['feature']

सुविधा के लेवल पर. इससे पता चलता है कि यह सुविधा, म्यूचुअली एक्सक्लूसिव कई वैकल्पिक सुविधाओं में से एक है. उदाहरण के लिए, सभी सैनिटाइज़र provides = ["sanitizer"] बता सकते हैं.

अगर उपयोगकर्ता एक साथ दो या इससे ज़्यादा खास सुविधाओं के लिए अनुरोध करता है, तो विकल्पों को सूची में शामिल करके गड़बड़ी ठीक करने के तरीके को बेहतर बनाया जा सकता है.

with_features = [
  with_feature_set(
    features = ['feature-1'],
    not_features = ['feature-2'],
  ),
]
फ़्लैग सेट-लेवल. कोई सुविधा एक से ज़्यादा फ़्लैग सेट के बारे में बता सकती है. with_features तय होने पर, फ़्लैग सेट बिल्ड निर्देश तक सिर्फ़ तब बड़ा होगा, जब कम से कम एक with_feature_set हो और दिए गए features सेट की सभी सुविधाएं चालू हों और not_features सेट में बताई गई सभी सुविधाएं बंद हों. अगर with_features के बारे में नहीं बताया गया है, तो हर कार्रवाई के लिए फ़्लैग सेट बिना किसी शर्त के लागू किया जाएगा.

कार्रवाइयाँ

कार्रवाइयों से, उन स्थितियों में बदलाव करने की सुविधा मिलती है जिनमें कोई कार्रवाई पूरी होती है. इसके लिए, यह नहीं कहा जाता कि कार्रवाई कैसे होगी. action_config उस टूल बाइनरी के बारे में बताता है जिससे कोई कार्रवाई शुरू होती है. वहीं, feature उस कॉन्फ़िगरेशन (फ़्लैग) के बारे में बताता है जो यह तय करता है कि कार्रवाई को शुरू करने पर वह टूल कैसे काम करता है.

सुविधाएं यह बताने के लिए कार्रवाइयों के बारे में बताती हैं कि Bazel कार्रवाइयों पर क्या असर होता है, क्योंकि कार्रवाइयां Bazel ऐक्शन ग्राफ़ में बदलाव कर सकती हैं. CcToolchainConfigInfo की सेवा देने वाली कंपनी में, ऐसी कार्रवाइयां मौजूद हैं जिनमें फ़्लैग और टूल मौजूद हैं, जैसे कि c++-compile. हर कार्रवाई को एक सुविधा से जोड़कर फ़्लैग असाइन किए जाते हैं.

हर कार्रवाई का नाम एक तरह की कार्रवाई के बारे में बताता है, जो Bazel करता है, जैसे कि कंपाइलिंग या लिंक करना. हालांकि, ऐक्शन और Bazel ऐक्शन टाइप के बीच मेनी-टू-वन रिलेशनशिप होता है. Bazel ऐक्शन टाइप, उन Java क्लास को दिखाता है जो कार्रवाई (जैसे कि CppCompileAction) को लागू करती है. खास तौर पर, नीचे दी गई टेबल में, "असेंबलर ऐक्शन" और "कंपाइलर ऐक्शन" CppCompileAction हैं, जबकि लिंक ऐक्शन CppLinkAction हैं.

असेंबलर कार्रवाइयां

कार्रवाई Description
preprocess-assemble प्री-प्रोसेसिंग के साथ असेंबल करें. आम तौर पर, .S फ़ाइलों के लिए.
assemble प्री-प्रोसेसिंग के बिना असेंबल करें. आम तौर पर, .s फ़ाइलों के लिए.

कंपाइलर कार्रवाइयां

कार्रवाई Description
cc-flags-make-variable CC_FLAGS को जेन रूल में फैलाता है.
c-compile सी. के तौर पर कंपाइल करें.
c++-compile C++ के तौर पर कंपाइल करें.
c++-header-parsing कंपाइलर पार्सर को हेडर फ़ाइल पर चलाएं, ताकि यह पक्का किया जा सके कि हेडर अपने-आप पूरा हो. ऐसा न करने पर, कंपाइल करने से जुड़ी गड़बड़ियां पैदा होंगी. यह सिर्फ़ मॉड्यूल के साथ काम करने वाले टूलचेन पर लागू होता है.
कार्रवाई Description
c++-link-dynamic-library शेयर की गई लाइब्रेरी को लिंक करें, जिसमें उसकी सभी डिपेंडेंसी शामिल हों.
c++-link-nodeps-dynamic-library सिर्फ़ cc_library स्रोतों वाली शेयर की गई लाइब्रेरी लिंक करें.
c++-link-executable चलने के लिए तैयार फ़ाइनल लाइब्रेरी को लिंक करें.

एआर (ऑगमेंटेड रिएलिटी) कार्रवाइयां

एआर (ऑगमेंटेड रिएलिटी) कार्रवाइयां, ar के ज़रिए ऑब्जेक्ट फ़ाइलों को संग्रह लाइब्रेरी (.a फ़ाइलें) में असेंबल करती हैं और नाम में कुछ सिमैंटिक्स कोड में बदल देती हैं.

कार्रवाई Description
c++-link-static-library एक स्टैटिक लाइब्रेरी (संग्रह) बनाएं.

LTO कार्रवाइयां

कार्रवाई Description
lto-backend ThinLTO ऐक्शन, नेटिव ऑब्जेक्ट में बिट कोड को कंपाइल करता है.
lto-index ThinLTO ऐक्शन जनरेट करने वाला ग्लोबल इंडेक्स.

action_config का इस्तेमाल करना

action_config, स्टारलार्क से जुड़ा स्ट्रक्चर है. यह फ़ीचर के हिसाब से तय किए गए, कार्रवाई और फ़्लैग के सेट के दौरान टूल (बाइनरी) के बारे में बताकर, बाज़ल ऐक्शन के बारे में बताता है. ये फ़्लैग, कार्रवाई को पूरा करने पर पाबंदियां लागू करते हैं.

action_config() कंस्ट्रक्टर में ये पैरामीटर हैं:

एट्रिब्यूट Description
action_name वह बैजल कार्रवाई जिससे यह कार्रवाई जुड़ी है. Bazel इस एट्रिब्यूट का इस्तेमाल, हर ऐक्शन के लिए इस्तेमाल होने वाले टूल और उसे लागू करने से जुड़ी ज़रूरी शर्तों का पता लगाने के लिए करता है.
tools शुरू करने के लिए एक्ज़ीक्यूटेबल. कार्रवाई पर लागू किया गया टूल, सूची का पहला टूल होगा. इसमें सुविधा का ऐसा सेट होगा जो सुविधा के कॉन्फ़िगरेशन से मेल खाता हो. डिफ़ॉल्ट मान देना ज़रूरी है.
flag_sets कार्रवाइयों के किसी ग्रुप पर लागू होने वाले फ़्लैग की सूची. जैसा कि किसी सुविधा के लिए होता है.
env_sets कार्रवाइयों के ग्रुप पर लागू होने वाली एनवायरमेंट पाबंदियों की सूची. किसी सुविधा के जैसा ही है.

action_config के लिए, दूसरी सुविधाओं और action_config की ज़रूरत पड़ सकती है और इन्हें लागू किया जा सकता है. इनके बारे में ऊपर बताया गया सुविधा संबंध तय किया जाता है. यह व्यवहार किसी सुविधा के जैसा ही होता है.

आखिरी दो एट्रिब्यूट, सुविधाओं पर उनसे जुड़े एट्रिब्यूट के लिए ज़रूरी नहीं हैं. इन्हें इसलिए शामिल किया जाता है, क्योंकि कुछ Bazel ऐक्शन के लिए कुछ फ़्लैग या एनवायरमेंट वैरिएबल की ज़रूरत होती है. इनका मकसद, ग़ैर-ज़रूरी action_config+feature पेयर से बचना होता है. आम तौर पर, एक से ज़्यादा action_config के बीच एक सुविधा शेयर करना बेहतर होता है.

आप एक ही टूलचेन में एक ही action_name के साथ, एक से ज़्यादा action_config तय नहीं कर सकते. यह टूल पाथ में साफ़ तौर पर जानकारी नहीं देता है. साथ ही, action_config के मकसद को लागू करता है - टूलचेन में किसी कार्रवाई की प्रॉपर्टी की जानकारी एक ही जगह पर साफ़ तौर पर दी जाती है.

टूल कंस्ट्रक्टर का इस्तेमाल करना

action_config अपने tools पैरामीटर की मदद से, टूल का कोई सेट तय कर सकता है. tool() कंस्ट्रक्टर को ये पैरामीटर मिलते हैं:

फ़ील्ड Description
tool_path विचाराधीन टूल का पाथ (मौजूदा जगह के हिसाब से).
with_features सुविधा के सेट की सूची, जिसमें से कम से कम एक का पूरा होना ज़रूरी है, ताकि यह टूल लागू किया जा सके.

किसी action_config के लिए, सिर्फ़ एक tool, Bazel ऐक्शन पर टूल पाथ और उसे लागू करने की ज़रूरी शर्तों को लागू करता है. एक टूल को चुनने के लिए, action_config पर tools एट्रिब्यूट का इस्तेमाल करके, उसे तब तक चुना जाता है, जब तक सुविधा के कॉन्फ़िगरेशन से मिलता-जुलता with_feature सेट वाला टूल नहीं मिल जाता (ज़्यादा जानकारी के लिए, इस पेज पर सुविधा के संबंध वाला लेख देखें). आपको अपनी टूल सूचियों के आखिर में किसी ऐसे डिफ़ॉल्ट टूल का इस्तेमाल करना चाहिए जो किसी खाली सुविधा कॉन्फ़िगरेशन से मेल खाता हो.

इस्तेमाल से जुड़ा उदाहरण

अलग-अलग क्रॉस-प्लैटफ़ॉर्म सिमैंटिक के साथ Bazel ऐक्शन को लागू करने के लिए, सुविधाओं और कार्रवाइयों का एक साथ इस्तेमाल किया जा सकता है. उदाहरण के लिए, macOS पर डीबग सिंबल जनरेट करने के लिए, कंपाइल ऐक्शन में सिंबल जनरेट करना ज़रूरी होता है. इसके बाद, कंप्रेस किए गए dsym संग्रह बनाने के लिए, लिंक ऐक्शन के दौरान एक खास टूल का इस्तेमाल करना होता है. इसके बाद, उस ऐप्लिकेशन बंडल और .plist फ़ाइलों को बनाने के लिए, उस संग्रह को डीकंप्रेस करना होता है, जिन्हें Xcode से इस्तेमाल किया जा सकता है.

Bazel की मदद से, इस प्रोसेस को इस तरह लागू किया जा सकता है. साथ ही, unbundle-debuginfo का इस्तेमाल Bazel कार्रवाई के तौर पर किया जा सकता है:

load("@rules_cc//cc:defs.bzl", "ACTION_NAMES")

action_configs = [
    action_config (
        config_name = ACTION_NAMES.cpp_link_executable,
        action_name = ACTION_NAMES.cpp_link_executable,
        tools = [
            tool(
                with_features = [
                    with_feature(features=["generate-debug-symbols"]),
                ],
                tool_path = "toolchain/mac/ld-with-dsym-packaging",
            ),
            tool (tool_path = "toolchain/mac/ld"),
        ],
    ),
]

features = [
    feature(
        name = "generate-debug-symbols",
        flag_sets = [
            flag_set (
                actions = [
                    ACTION_NAMES.c_compile,
                    ACTION_NAMES.cpp_compile
                ],
                flag_groups = [
                    flag_group(
                        flags = ["-g"],
                    ),
                ],
            )
        ],
        implies = ["unbundle-debuginfo"],
   ),
]

fission का इस्तेमाल करने वाले Linux के लिए यही सुविधा अलग-अलग तरीके से लागू की जा सकती है. इसके अलावा, .pdb फ़ाइलें बनाने वाले Windows के लिए भी इसी सुविधा को लागू किया जा सकता है. उदाहरण के लिए, fission के आधार पर डीबग सिंबल जनरेट करने के लिए, ऐसा दिख सकता है:

load("@rules_cc//cc:defs.bzl", "ACTION_NAMES")

action_configs = [
    action_config (
        name = ACTION_NAMES.cpp_compile,
        tools = [
            tool(
                tool_path = "toolchain/bin/gcc",
            ),
        ],
    ),
]

features = [
    feature (
        name = "generate-debug-symbols",
        requires = [with_feature_set(features = ["dbg"])],
        flag_sets = [
            flag_set(
                actions = [ACTION_NAMES.cpp_compile],
                flag_groups = [
                    flag_group(
                        flags = ["-gsplit-dwarf"],
                    ),
                ],
            ),
            flag_set(
                actions = [ACTION_NAMES.cpp_link_executable],
                flag_groups = [
                    flag_group(
                        flags = ["-Wl", "--gdb-index"],
                    ),
                ],
            ),
      ],
    ),
]

ग्रुप की शिकायत करें

CcToolchainConfigInfo की मदद से, फ़्लैग को ऐसे ग्रुप में बांटा जा सकता है जो किसी खास मकसद को पूरा करते हैं. पहले से तय किए गए वैरिएबल का इस्तेमाल करके फ़्लैग वैल्यू में फ़्लैग तय किया जा सकता है. बिल्ड कमांड में फ़्लैग जोड़ते समय, कंपाइलर इसे बड़ा कर देता है. उदाहरण के लिए:

flag_group (
    flags = ["%{output_file_path}"],
)

इस मामले में, फ़्लैग का कॉन्टेंट, कार्रवाई के आउटपुट फ़ाइल पाथ से बदल दिया जाएगा.

फ़्लैग ग्रुप को बिल्ड निर्देश में उसी क्रम में बड़ा किया जाता है जिस क्रम में वे सूची में, ऊपर से नीचे, बाएं से दाएं दिखते हैं.

बिल्ड निर्देश में जोड़े जाने पर, जिन फ़्लैग को अलग-अलग वैल्यू के साथ दोहराने की ज़रूरत होती है उनके लिए फ़्लैग ग्रुप, list टाइप के वैरिएबल को इटरेट कर सकता है. उदाहरण के लिए, list टाइप का include_path वैरिएबल:

flag_group (
    iterate_over = "include_paths",
    flags = ["-I%{include_paths}"],
)

include_paths सूची में हर पाथ एलिमेंट के लिए -I<path> तक बढ़ता है. फ़्लैग ग्रुप के एलान के मुख्य भाग में मौजूद सभी फ़्लैग (या flag_group) को एक यूनिट के तौर पर बड़ा किया जाता है. उदाहरण के लिए:

flag_group (
    iterate_over = "include_paths",
    flags = ["-I", "%{include_paths}"],
)

include_paths सूची में हर पाथ एलिमेंट के लिए -I <path> तक बढ़ता है.

कोई वैरिएबल कई बार दोहराया जा सकता है. उदाहरण के लिए:

flag_group (
    iterate_over = "include_paths",
    flags = ["-iprefix=%{include_paths}", "-isystem=%{include_paths}"],
)

इसमें बढ़ता है:

-iprefix=<inc0> -isystem=<inc0> -iprefix=<inc1> -isystem=<inc1>

वैरिएबल, डॉट-नोटेशन का इस्तेमाल करके ऐक्सेस किए जा सकने वाले स्ट्रक्चर के साथ हो सकते हैं. उदाहरण के लिए:

flag_group (
    flags = ["-l%{libraries_to_link.name}"],
)

स्ट्रक्चर को नेस्ट किया जा सकता है और इनमें क्रम भी हो सकते हैं. नाम को मेल खाने से रोकने और साफ़ तौर पर जानकारी देने के लिए, आपको फ़ील्ड के ज़रिए पूरा पाथ बताना होगा. उदाहरण के लिए:

flag_group (
    iterate_over = "libraries_to_link",
    flag_groups = [
        flag_group (
            iterate_over = "libraries_to_link.shared_libraries",
            flags = ["-l%{libraries_to_link.shared_libraries.name}"],
        ),
    ],
)

शर्त के साथ बड़ा करना

फ़्लैग ग्रुप, expand_if_available, expand_if_not_available, expand_if_true, expand_if_false या expand_if_equal एट्रिब्यूट का इस्तेमाल करके, किसी खास वैरिएबल या उसके फ़ील्ड के आधार पर, बड़े पैमाने पर किए जाने वाले एक्सपैंशन की सुविधा देते हैं. उदाहरण के लिए:

flag_group (
    iterate_over = "libraries_to_link",
    flag_groups = [
        flag_group (
            iterate_over = "libraries_to_link.shared_libraries",
            flag_groups = [
                flag_group (
                    expand_if_available = "libraries_to_link.shared_libraries.is_whole_archive",
                    flags = ["--whole_archive"],
                ),
                flag_group (
                    flags = ["-l%{libraries_to_link.shared_libraries.name}"],
                ),
                flag_group (
                    expand_if_available = "libraries_to_link.shared_libraries.is_whole_archive",
                    flags = ["--no_whole_archive"],
                ),
            ],
        ),
    ],
)

CCToolchainConfigInfo रेफ़रंस

इस सेक्शन में, C++ नियमों को कॉन्फ़िगर करने के लिए ज़रूरी बिल्ड वैरिएबल, सुविधाओं, और अन्य जानकारी का रेफ़रंस दिया गया है.

CCToolchainConfigInfo बिल्ड वैरिएबल

यहां CcToolchainConfigInfo बिल्ड वैरिएबल का रेफ़रंस दिया गया है.

वैरिएबल कार्रवाई Description
source_file compile कंपाइल करने के लिए सोर्स फ़ाइल.
input_file पट्टी पट्टी के लिए आर्टफ़ैक्ट.
output_file compile कंपाइलेशन आउटपुट.
output_assembly_file compile एसेंबली फ़ाइल उत्सर्जित की गई. सिर्फ़ तब लागू होता है, जब compile कार्रवाई से, असेंबली टेक्स्ट निकाला जाता है. आम तौर पर, ऐसा --save_temps फ़्लैग का इस्तेमाल करते समय होता है. कॉन्टेंट, output_file के जैसा ही है.
output_preprocess_file compile पहले से प्रोसेस किया गया आउटपुट. यह सिर्फ़ उन कार्रवाइयों को कंपाइल करने पर लागू होता है जो सोर्स फ़ाइलों को पहले से ही प्रोसेस करती हैं. आम तौर पर, ऐसा --save_temps फ़्लैग का इस्तेमाल करते समय किया जाता है. कॉन्टेंट, output_file के जैसा ही है.
includes compile कंपाइलर की मदद से, फ़ाइलों के क्रम को, कंपाइल किए गए सोर्स में बिना शर्त के शामिल किया जाना चाहिए.
include_paths compile क्रम वाली डायरेक्ट्री, जिनमें कंपाइलर हेडर की खोज करता है. इसके लिए, #include<foo.h> और #include "foo.h" का इस्तेमाल किया जाता है.
quote_include_paths compile -iquote के क्रम में - ऐसी डायरेक्ट्री शामिल होती हैं जिसमें कंपाइलर, #include "foo.h" का इस्तेमाल करके हेडर की खोज करता है.
system_include_paths compile -isystem के क्रम में - ऐसी डायरेक्ट्री शामिल होती हैं जिसमें कंपाइलर, #include <foo.h> का इस्तेमाल करके हेडर की खोज करता है.
dependency_file compile कंपाइलर से जनरेट की गई .d डिपेंडेंसी फ़ाइल.
preprocessor_defines compile defines का क्रम, जैसे कि --DDEBUG.
pic compile आउटपुट को पोज़िशन पर निर्भर न होने वाले कोड के तौर पर कंपाइल करता है.
gcov_gcno_file compile gcov कवरेज फ़ाइल.
per_object_debug_info_file compile हर ऑब्जेक्ट के डीबग की जानकारी (.dwp) फ़ाइल.
stripotps पट्टी stripopts का क्रम.
legacy_compile_flags compile CROSSTOOL के लेगसी फ़ील्ड के फ़्लैग का क्रम, जैसे कि compiler_flag, optional_compiler_flag, cxx_flag, और optional_cxx_flag.
user_compile_flags compile copt नियम वाले एट्रिब्यूट या --copt, --cxxopt, और --conlyopt फ़्लैग के फ़्लैग का क्रम.
unfiltered_compile_flags compile unfiltered_cxx_flag के लेगसी CROSSTOOL फ़ील्ड या unfiltered_compile_flags सुविधा से फ़्लैग का क्रम. इन्हें nocopts नियम वाले एट्रिब्यूट के हिसाब से फ़िल्टर नहीं किया जाता.
sysroot sysroot.
runtime_library_search_directories लिंक लिंकर रनटाइम सर्च पाथ में एंट्री (आम तौर पर, -rpath फ़्लैग के साथ सेट की जाती है).
library_search_directories लिंक लिंकर के खोज पाथ में मौजूद एंट्री (आम तौर पर, -L फ़्लैग के साथ सेट की जाती हैं).
libraries_to_link लिंक लिंकर को शुरू करने के दौरान, इनपुट के तौर पर लिंक करने के लिए फ़ाइलें देने वाले फ़्लैग.
def_file_path लिंक MSVC के साथ Windows पर इस्तेमाल की गई डीएफ़ फ़ाइल की जगह.
linker_param_file लिंक कमांड लाइन की लंबाई की सीमा पार करने के लिए bazel की बनाई गई लिंकर पैरामीटर फ़ाइल की जगह.
output_execpath लिंक लिंकर के आउटपुट का एक्ज़ीक्यूशन.
generate_interface_library लिंक "yes" या "no" इस आधार पर तय होता है कि इंटरफ़ेस लाइब्रेरी जनरेट करनी चाहिए या नहीं.
interface_library_builder_path लिंक इंटरफ़ेस लाइब्रेरी बिल्डर टूल का पाथ.
interface_library_input_path लिंक इंटरफ़ेस लाइब्रेरी ifso बिल्डर टूल के लिए इनपुट.
interface_library_output_path लिंक ifso बिल्डर टूल का इस्तेमाल करके इंटरफ़ेस लाइब्रेरी जनरेट करने के लिए पाथ.
legacy_link_flags लिंक लेगसी CROSSTOOL फ़ील्ड से मिलने वाले लिंकर फ़्लैग.
user_link_flags लिंक --linkopt या linkopts एट्रिब्यूट से मिलने वाले लिंकर फ़्लैग.
symbol_counts_output लिंक प्रतीक की गिनती लिखने के लिए पाथ.
linkstamp_paths लिंक लिंकस्टैंप पाथ देने वाला बिल्ड वैरिएबल.
force_pic लिंक इस वैरिएबल के मौजूद होने का मतलब है कि पीआईसी/पीआईई कोड जनरेट किया जाना चाहिए (Bazel विकल्प `--force_pic` पास किया गया था).
strip_debug_symbols लिंक इस वैरिएबल के मौजूद होने का मतलब है कि डीबग सिंबल को हटा दिया जाना चाहिए.
is_cc_test लिंक सही है, जब मौजूदा कार्रवाई cc_test लिंक करने की कार्रवाई है, नहीं तो 'गलत' है.
is_using_fission कंपाइल, लिंक इस वैरिएबल के मौजूद होने से पता चलता है कि फ़िशन (हर ऑब्जेक्ट डीबग की जानकारी) चालू है. डीबग की जानकारी, .o फ़ाइलों के बजाय .dwo फ़ाइलों में होगी और कंपाइलर और लिंकर को यह पता होना ज़रूरी है.
fdo_instrument_path कंपाइल, लिंक उस डायरेक्ट्री का पाथ जिसमें एफ़डीओ इंस्ट्रुमेंटेशन प्रोफ़ाइल सेव है.
fdo_profile_path compile एफ़डीओ प्रोफ़ाइल का पाथ.
fdo_prefetch_hints_path compile कैश प्रीफ़ेच प्रोफ़ाइल का पाथ.
csfdo_instrument_path कंपाइल, लिंक उस डायरेक्ट्री का पाथ जिसमें कॉन्टेक्स्ट सेंसिटिव एफ़डीओ इंस्ट्रुमेंटेशन प्रोफ़ाइल सेव की गई है.

लोकप्रिय सुविधाएं

सुविधाओं और उनके चालू होने की स्थितियों के बारे में नीचे जानकारी दी गई है.

सुविधा दस्तावेज़ के रूप में
opt | dbg | fastbuild यह सुविधा, कंपाइलेशन मोड के आधार पर डिफ़ॉल्ट रूप से चालू रहती है.
static_linking_mode | dynamic_linking_mode लिंक करने के मोड के आधार पर, यह सेटिंग डिफ़ॉल्ट रूप से चालू होती है.
per_object_debug_info अगर supports_fission सुविधा के बारे में बताया गया हो और चालू किया गया हो और मौजूदा कंपाइलेशन मोड, --fission फ़्लैग में दिया गया हो, तो यह विकल्प चालू होता है.
supports_start_end_lib अगर यह चालू है (और --start_end_lib विकल्प सेट है), तो Bazel स्टैटिक लाइब्रेरी से लिंक नहीं किया जाएगा. इसके बजाय, यह सीधे ऑब्जेक्ट से लिंक करने के लिए, --start-lib/--end-lib लिंकर विकल्पों का इस्तेमाल करेगा. यह तेज़ी से बिल्ड करता है, क्योंकि Bazel को स्टैटिक लाइब्रेरी बनाने की ज़रूरत नहीं होती.
supports_interface_shared_libraries यह नीति चालू होने पर (और --interface_shared_objects विकल्प सेट है), Bazel उन टारगेट को लिंक करेगा जिनमें इंटरफ़ेस की शेयर की गई लाइब्रेरी के साथ linkstatic को 'गलत है' (डिफ़ॉल्ट रूप से cc_test) पर सेट किया गया है. इससे उन्हें फिर से तेज़ी से जोड़ा जा सकता है.
supports_dynamic_linker अगर यह सेटिंग चालू की जाती है, तो C++ नियमों को पता चल जाएगा कि टूलचेन, शेयर की गई लाइब्रेरी बना सकता है.
static_link_cpp_runtimes अगर इस सुविधा को चालू किया जाता है, तो Bazel, C++ रनटाइम को स्टैटिक रूप से और डाइनैमिक लिंकिंग मोड में लिंक करेगा. लिंक करने के मोड के आधार पर, cc_toolchain.static_runtime_lib या cc_toolchain.dynamic_runtime_lib एट्रिब्यूट में दिए गए आर्टफ़ैक्ट, लिंक करने की कार्रवाइयों में जोड़े जाएंगे.
supports_pic चालू होने पर, टूलचेन को डाइनैमिक लाइब्रेरी के लिए पीआईसी ऑब्जेक्ट का इस्तेमाल करने का पता चल जाता है. जब भी पीआईसी कंपाइलेशन की ज़रूरत होती है, तब `पिक` वैरिएबल मौजूद होता है. अगर यह सुविधा डिफ़ॉल्ट रूप से चालू नहीं है और `--force_pic` पास की गई है, तो Bazel `supports_pic` का अनुरोध करेगा और पुष्टि करेगा कि यह सुविधा चालू है या नहीं. अगर सुविधा मौजूद नहीं है या उसे चालू नहीं किया जा सकता, तो `--force_pic` का इस्तेमाल नहीं किया जा सकता.
static_linking_mode | dynamic_linking_mode लिंक करने के मोड के आधार पर, यह सेटिंग डिफ़ॉल्ट रूप से चालू होती है.
no_legacy_features C++ कॉन्फ़िगरेशन में, Bazel को लेगसी सुविधाएं जोड़ने से रोकता है. नीचे सुविधाओं की पूरी सूची देखें.

लेगसी सुविधाएं पैचिंग लॉजिक

पुराने सिस्टम के साथ काम करने की सुविधा के लिए, Bazel, टूलचेन की सुविधाओं में ये बदलाव लागू करता है:

  • legacy_compile_flags सुविधा को टूलचेन के सबसे ऊपर ले जाता है
  • default_compile_flags सुविधा को टूलचेन के सबसे ऊपर ले जाता है
  • इससे टूलचेन के सबसे ऊपर dependency_file (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर pic (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर per_object_debug_info (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर preprocessor_defines (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर includes (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर include_paths (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर fdo_instrument (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर fdo_optimize (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर cs_fdo_instrument (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर cs_fdo_optimize (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर fdo_prefetch_hints (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर autofdo (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर build_interface_libraries (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर dynamic_library_linker_tool (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर symbol_counts (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर shared_flag (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर linkstamps (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर output_execpath_flags (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर runtime_library_search_directories (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर library_search_directories (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर archiver_flags (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर libraries_to_link (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर force_pic_flags (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर user_link_flags (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर legacy_link_flags (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर static_libgcc (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर fission_support (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर strip_debug_symbols (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर coverage (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर llvm_coverage_map_format (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • इससे टूलचेन के सबसे ऊपर gcc_coverage_map_format (अगर मौजूद नहीं है) सुविधा जुड़ जाती है
  • fully_static_link (अगर मौजूद नहीं है) की सुविधा को टूलचेन के नीचे जोड़ता है
  • user_compile_flags (अगर मौजूद नहीं है) की सुविधा को टूलचेन के नीचे जोड़ता है
  • sysroot (अगर मौजूद नहीं है) की सुविधा को टूलचेन के नीचे जोड़ता है
  • unfiltered_compile_flags (अगर मौजूद नहीं है) की सुविधा को टूलचेन के नीचे जोड़ता है
  • linker_param_file (अगर मौजूद नहीं है) की सुविधा को टूलचेन के नीचे जोड़ता है
  • compiler_input_flags (अगर मौजूद नहीं है) की सुविधा को टूलचेन के नीचे जोड़ता है
  • compiler_output_flags (अगर मौजूद नहीं है) की सुविधा को टूलचेन के नीचे जोड़ता है

यह सुविधाओं की एक लंबी सूची है. योजना है कि इनसे छुटकारा पाने के लिए स्टारलार्क में क्रॉसटूल पूरा हो जाए. दिलचस्पी रखने वाले लोग, CppActionConfigs में इसे लागू करने के तरीके के बारे में जानते हैं. साथ ही, प्रोडक्शन टूलचेन में no_legacy_features को जोड़ें, ताकि टूलचेन को और ज़्यादा स्टैंडअलोन बनाया जा सके.