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

समस्या की शिकायत करें स्रोत देखें

खास जानकारी

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

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

  • कंपाइलर, पतला LTO, मॉड्यूल, डाइनैमिक लिंकिंग या PIC (रैंक इंडिपेंडेंट कोड) के साथ काम करता है या नहीं.
  • 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, --cpu | --compiler की मदद से cc_toolchain_suite.toolchains एट्रिब्यूट से संबंधित एंट्री को चुनता है. अगर Bazel को कोई मिलती-जुलती एंट्री नहीं मिलती है, तो वह गड़बड़ी की जानकारी देता है.

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

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

टूलचेन को चुनने के बाद, Starlark नियम में उससे जुड़े feature और action_config ऑब्जेक्ट, बिल्ड (यानी कि ऐसे आइटम जिनके बारे में बाद में बताया गया है) के कॉन्फ़िगरेशन को कंट्रोल करते हैं. इन मैसेज की मदद से, 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 नियम के तहत, सीधे तौर पर इस्तेमाल के लिए ज़्यादा विस्तृत पाबंदियां तय की जा सकती हैं. इनके उदाहरण हैं:

सीमा जानकारी
requires = [
   feature_set (features = [
       'feature-name-1',
       'feature-name-2'
   ]),
]
सुविधा-लेवल. यह सुविधा सिर्फ़ तब काम करती है, जब बताई गई ज़रूरी सुविधाएं चालू हों. उदाहरण के लिए, जब कोई सुविधा सिर्फ़ कुछ बिल्ड मोड (opt, dbg या fastbuild) में काम करती है, तो एक से ज़्यादा `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 ऐक्शन टाइप, कार्रवाई (जैसे कि CppCompileAction) को लागू करने वाली Java क्लास के बारे में बताता है. खास तौर पर, नीचे दी गई टेबल में "असेंबलर ऐक्शन" और "कंपलर ऐक्शन" CppCompileAction हैं, जबकि लिंक ऐक्शन CppLinkAction हैं.

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

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

कंपाइलर ऐक्शन

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

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

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

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

एलटीओ कार्रवाइयां

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

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

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

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

एट्रिब्यूट जानकारी
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() कंस्ट्रक्टर इन पैरामीटर का इस्तेमाल करता है:

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

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

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

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

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

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

action_configs = [
    action_config (
        action_name = ACTION_NAMES.cpp_link_executable,
        tools = [
            tool(
                with_features = [
                    with_feature(features=["generate-debug-symbols"]),
                ],
                path = "toolchain/mac/ld-with-dsym-packaging",
            ),
            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"],
   ),
]

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

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

action_configs = [
    action_config (
        name = ACTION_NAMES.cpp_compile,
        tools = [
            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_execpath}"],
)

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

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

बिल्ड कमांड में जोड़े जाने पर, जिन फ़्लैग को अलग-अलग वैल्यू के साथ दोहराने की ज़रूरत होती है उनके लिए, फ़्लैग ग्रुप 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 बिल्ड वैरिएबल का रेफ़रंस दिया गया है.

वैरिएबल कार्रवाई जानकारी
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 एट्रिब्यूट से मिलने वाले लिंकर फ़्लैग.
linkstamp_paths लिंक लिंकस्टैंप पाथ देने वाला बिल्ड वैरिएबल.
force_pic लिंक इस वैरिएबल के मौजूद होने से पता चलता है कि PIC/PIE कोड जनरेट किया जाना चाहिए (Bazel विकल्प `--force_pic` पास किया गया).
strip_debug_symbols लिंक इस वैरिएबल के मौजूद होने का मतलब है कि डीबग सिंबल को हटा देना चाहिए.
is_cc_test लिंक सही है, जब मौजूदा कार्रवाई cc_test लिंक करने की कार्रवाई है, नहीं तो 'गलत' है.
is_using_fission कंपाइल, लिंक इस वैरिएबल के मौजूद होने से पता चलता है कि फ़िशन (हर ऑब्जेक्ट डीबग की जानकारी) चालू है. डीबग की जानकारी, .o फ़ाइलों के बजाय .dwo फ़ाइलों में होगी. साथ ही, कंपाइलर और लिंकर को यह जानकारी होना ज़रूरी है.
fdo_instrument_path कंपाइल, लिंक उस डायरेक्ट्री का पाथ जिसमें FDO इंस्ट्रुमेंटेशन प्रोफ़ाइल सेव होती है.
fdo_profile_path compile FDO प्रोफ़ाइल का पाथ.
fdo_prefetch_hints_path compile कैश प्रीफ़ेच प्रोफ़ाइल का पाथ.
cs_fdo_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 (अगर मौजूद नहीं है) सुविधा जोड़ता है
  • टूलचेन के सबसे ऊपर 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 की सुविधा जुड़ जाती है (अगर मौजूद नहीं है)

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