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

किसी समस्या की शिकायत करें सोर्स देखें Nightly · 8.0 7.4 . 7.3 · 7.2 · 7.1 · 7.0 · 6.5

खास जानकारी

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

Bazel को यह जानकारी चाहिए:

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

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

CcToolchainConfigInfo एक ऐसा प्रोवाइडर है जो Bazel के C++ नियमों के काम करने के तरीके को कॉन्फ़िगर करने के लिए, ज़रूरी जानकारी देता है. डिफ़ॉल्ट रूप से, Bazel आपके बिल्ड के लिए CcToolchainConfigInfo को अपने-आप कॉन्फ़िगर करता है. हालांकि, आपके पास इसे मैन्युअल तरीके से कॉन्फ़िगर करने का विकल्प होता है. इसके लिए, आपको एक Starlark नियम की ज़रूरत होगी जो CcToolchainConfigInfo उपलब्ध कराता है. साथ ही, आपको अपने नियम में cc_toolchain के toolchain_config एट्रिब्यूट को दिखाना होगा. CcToolchainConfigInfo बनाने के लिए, cc_common.create_cc_toolchain_config_info() को कॉल करें. आपको @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 विकल्पों से पास किए गए कॉन्फ़िगरेशन फ़्लैग
  • एनवायरमेंट वैरिएबल
  • उस सैंडबॉक्स में ज़रूरी आर्टफ़ैक्ट जिसमें कार्रवाई की जाती है

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

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

टूलचेन चुनना

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

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

  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 बाइनरी में बदलाव किए बिना, Bazel में C++ की सभी सुविधाएं लागू की जा सकती हैं. C++ नियमों में कई यूनीक कार्रवाइयां की सुविधा होती है. इनके बारे में ज़्यादा जानकारी Bazel सोर्स कोड में दी गई है.

सुविधाएं

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

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

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

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

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

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

प्रॉडक्ट के बीच संबंध

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

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

असेंबलर ऐक्शन

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

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

कार्रवाई जानकारी
cc-flags-make-variable CC_FLAGS को genrules में भेजता है.
c-compile C के तौर पर कंपाइल करें.
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 कार्रवाई.

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

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

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

एट्रिब्यूट जानकारी
action_name वह Bazel कार्रवाई जिससे यह कार्रवाई जुड़ी है. 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 के लिए, सिर्फ़ एक 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 (
        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"],
   ),
]

fission का इस्तेमाल करने वाले Linux या .pdb फ़ाइलें बनाने वाले Windows के लिए, एक ही सुविधा को पूरी तरह से अलग तरीके से लागू किया जा सकता है. उदाहरण के लिए, 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 कंपाइल करना कंपाइल करने के लिए सोर्स फ़ाइल.
input_file स्ट्रिप वह आर्टफ़ैक्ट जिससे डेटा हटाना है.
output_file कंपाइल करना कंपाइलेशन का आउटपुट.
output_assembly_file कंपाइल करना जनरेट की गई असेंबली फ़ाइल. यह सिर्फ़ तब लागू होता है, जब compile कार्रवाई, आम तौर पर --save_temps फ़्लैग का इस्तेमाल करते समय, असेंबली टेक्स्ट को उत्सर्जित करती है. कॉन्टेंट, output_file के लिए मौजूद कॉन्टेंट जैसा ही है.
output_preprocess_file कंपाइल करना पहले से प्रोसेस किया गया आउटपुट. यह सिर्फ़ उन Compile ऐक्शन पर लागू होता है जो सिर्फ़ सोर्स फ़ाइलों को प्रीप्रोसेस करते हैं. आम तौर पर, ऐसा --save_temps फ़्लैग का इस्तेमाल करते समय होता है. कॉन्टेंट, output_file के लिए मौजूद कॉन्टेंट जैसा ही है.
includes कंपाइल करना उन फ़ाइलों का क्रम जिन्हें कंपाइलर को बिना किसी शर्त के, कंपाइल किए गए सोर्स में शामिल करना चाहिए.
include_paths कंपाइल करना सीक्वेंस डायरेक्ट्री, जिनमें कंपाइलर, #include<foo.h> और #include "foo.h" का इस्तेमाल करके शामिल किए गए हेडर खोजता है.
quote_include_paths कंपाइल करना -iquote के क्रम में ये शामिल हैं - ऐसी डायरेक्ट्री जिनमें कंपाइलर, #include "foo.h" का इस्तेमाल करके शामिल किए गए हेडर खोजता है.
system_include_paths कंपाइल करना -isystem के क्रम में ये शामिल हैं - ऐसी डायरेक्ट्री जिनमें कंपाइलर, #include <foo.h> का इस्तेमाल करके शामिल किए गए हेडर खोजता है.
dependency_file कंपाइल करना कंपाइलर से जनरेट की गई .d डिपेंडेंसी फ़ाइल.
preprocessor_defines कंपाइल करना defines का क्रम, जैसे कि --DDEBUG.
pic कंपाइल करना आउटपुट को पोज़िशन-इंडिपेंडेंट कोड के तौर पर कंपाइल करता है.
gcov_gcno_file कंपाइल करना gcov कवरेज फ़ाइल.
per_object_debug_info_file कंपाइल करना हर ऑब्जेक्ट के लिए डीबग की जानकारी (.dwp) वाली फ़ाइल.
stripotps स्ट्रिप stripopts का क्रम.
legacy_compile_flags कंपाइल करना लेगसी CROSSTOOL फ़ील्ड से मिले फ़्लैग का क्रम, जैसे कि compiler_flag, optional_compiler_flag, cxx_flag, और optional_cxx_flag.
user_compile_flags कंपाइल करना copt नियम एट्रिब्यूट या --copt, --cxxopt, और --conlyopt फ़्लैग में से किसी एक का फ़्लैग क्रम.
unfiltered_compile_flags कंपाइल करना 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 पर इस्तेमाल की जाने वाली def फ़ाइल की जगह.
linker_param_file लिंक कमांड लाइन की लंबाई की सीमा को कम करने के लिए, bazel की बनाई गई लिंकर पैरामीटर फ़ाइल की जगह.
output_execpath लिंक लिंकर के आउटपुट का 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 लिंक करने की कार्रवाई है, तो True. अगर नहीं, तो False.
is_using_fission कंपाइल करना, लिंक करना इस वैरिएबल की मौजूदगी से पता चलता है कि फ़िज़न (हर ऑब्जेक्ट के लिए डीबग जानकारी) चालू है. डीबग की जानकारी, .o फ़ाइलों के बजाय .dwo फ़ाइलों में होगी. कंपाइलर और लिंकर को इसकी जानकारी होनी चाहिए.
fdo_instrument_path कंपाइल करना, लिंक करना उस डायरेक्ट्री का पाथ जिसमें FDO इंस्ट्रूमेंटेशन प्रोफ़ाइल सेव की जाती है.
fdo_profile_path कंपाइल करना एफ़डीओ प्रोफ़ाइल का पाथ.
fdo_prefetch_hints_path कंपाइल करना कैश मेमोरी में प्रीफ़ेच की गई प्रोफ़ाइल का पाथ.
csfdo_instrument_path कंपाइल करना, लिंक करना उस डायरेक्ट्री का पाथ जिसमें कॉन्टेक्स्ट के हिसाब से काम करने वाली FDO इंस्ट्रूमेंटेशन प्रोफ़ाइल सेव की जाती है.

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

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

सुविधा दस्तावेज़ के रूप में
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 अगर यह विकल्प चालू है, तो टूलचेन को डायनैमिक लाइब्रेरी के लिए PIC ऑब्जेक्ट का इस्तेमाल करने की जानकारी होगी. जब भी PIC कंपाइलेशन की ज़रूरत होती है, तब `pic` वैरिएबल मौजूद होता है. अगर यह सुविधा डिफ़ॉल्ट रूप से चालू नहीं है और `--force_pic` का इस्तेमाल किया गया है, तो Bazel, `supports_pic` का अनुरोध करेगा और पुष्टि करेगा कि यह सुविधा चालू है या नहीं. अगर यह सुविधा मौजूद नहीं है या इसे चालू नहीं किया जा सका, तो `--force_pic` का इस्तेमाल नहीं किया जा सकता.
static_linking_mode | dynamic_linking_mode लिंक करने के मोड के आधार पर, डिफ़ॉल्ट रूप से चालू होता है.
no_legacy_features Bazel को C++ कॉन्फ़िगरेशन में लेगसी सुविधाएं जोड़ने से रोकता है. सुविधाओं की पूरी सूची यहां देखें.

लेगसी सुविधाओं को पैच करने का लॉजिक

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 जोड़ें, ताकि टूलचेन को ज़्यादा स्टैंडअलोन बनाया जा सके.