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

7.3 · 7.2 · 7.1 · 7.0 · 6.5

खास जानकारी

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

बेज़ल को यह जानकारी होनी चाहिए:

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

अगर कंपाइलर में एक से ज़्यादा आर्किटेक्चर के लिए सहायता है, तो 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++ टारगेट, विश्लेषण के चरण में आता है, तो Baze, 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 विकल्प का इस्तेमाल करके, Bazel को टारगेट पर ले जाता है.

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

    • अगर --compiler का विकल्प चुना गया है, तो Basel, cc_toolchain_suite.toolchains एट्रिब्यूट से जुड़ी एंट्री को --cpu | --compiler वाली वैल्यू से चुनता है. अगर 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 फ़ाइल सेटिंग, और दूसरे वैरिएबल पर निर्भर करती हैं.

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

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

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

किसी दिए गए action_config के लिए, सिर्फ़ एक tool इसके टूल पाथ और बेज़ेल ऐक्शन पर लागू करने की ज़रूरी शर्तों को लागू करता है. किसी टूल को तब तक 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 बिल्ड वैरिएबल का रेफ़रंस दिया गया है.

वैरिएबल कार्रवाई जानकारी
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 कंपाइल करना compiler_flag, optional_compiler_flag, cxx_flag, और optional_cxx_flag जैसे लेगसी CROSSTOOL फ़ील्ड से फ़्लैग का क्रम.
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 एट्रिब्यूट से मिलने वाले लिंकर फ़्लैग.
symbol_counts_output लिंक वह पाथ जिसमें सिंबल की संख्या लिखी जानी है.
linkstamp_paths लिंक लिंकस्टैंप पाथ देने वाला बिल्ड वैरिएबल.
force_pic लिंक इस वैरिएबल के मौजूद होने से यह पता चलता है कि PIC/PIE कोड जनरेट करना ज़रूरी है (Baज़ल विकल्प `--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 लिंकर के विकल्पों का इस्तेमाल करेगा. इससे बिल्ड तेज़ी से बढ़ता है, क्योंकि Basel को स्टैटिक लाइब्रेरी बनाने की ज़रूरत नहीं है.
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 यह C++ कॉन्फ़िगरेशन के मौजूद होने पर, Baज़ल को 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 (अगर मौजूद नहीं है) सुविधा जोड़ता है
  • टूलचेन के सबसे ऊपर 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 (अगर मौजूद नहीं है) सुविधा जोड़ता है

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