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

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

खास जानकारी

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

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

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

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

CcToolchainConfigInfo एक ऐसी कंपनी है जो Basel के C++ नियमों के व्यवहार को कॉन्फ़िगर करने के लिए, ज़रूरी बारीकी से जानकारी देती है. डिफ़ॉल्ट रूप से, Baze आपके बिल्ड के लिए CcToolchainConfigInfo को अपने-आप कॉन्फ़िगर कर देता है. हालांकि, आपके पास इसे मैन्युअल तरीके से कॉन्फ़िगर करने का विकल्प होता है. इसके लिए, आपको स्टारलार्क नियम की ज़रूरत है, जो 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 विकल्प का इस्तेमाल करके, बैज को टारगेट पर पॉइंट करता है.

  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 एट्रिब्यूट से उससे जुड़ी एंट्री चुनता है.

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

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

सुविधाएं

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

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

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

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

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

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

सुविधाओं के साथ ऐसेट जोड़ना

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

सीमा जानकारी
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 हैं.

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

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

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

कार्रवाई जानकारी
cc-flags-make-variable CC_FLAGS को genrules में भेजता है.
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 थिनएलटीओ ऐक्शन, ग्लोबल इंडेक्स जनरेट कर रहा है.

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

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

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

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

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

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

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

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

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

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

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

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

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

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 कंपाइल करें पहले से प्रोसेस किया गया आउटपुट. सिर्फ़ उन कार्रवाइयों को इकट्ठा करने पर लागू होती है जो सिर्फ़ सोर्स फ़ाइलों को पहले से प्रोसेस करती हैं. आम तौर पर, ऐसा तब होता है, जब --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 लिंक कमांड लाइन की लंबाई की सीमा से बचने के लिए, बैजर ने लिंकर पैरामीटर फ़ाइल की जगह की जानकारी का इस्तेमाल किया.
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 कोड जनरेट करना ज़रूरी है (Baज़ल विकल्प `--force_pic` पास किया गया था).
strip_debug_symbols लिंक इस वेरिएबल के मौजूद होने से पता चलता है कि डीबग सिंबल हटा दिए जाने चाहिए.
is_cc_test लिंक सही है, जब मौजूदा कार्रवाई cc_test लिंक करने की कार्रवाई है, नहीं तो गलत.
is_using_fission कंपाइल, लिंक इस वैरिएबल की मौजूदगी से पता चलता है कि फ़िज़न (हर ऑब्जेक्ट के लिए डीबग जानकारी) चालू है. डीबग की जानकारी, .o फ़ाइलों के बजाय .dwo फ़ाइलों में होगी. कंपाइलर और लिंकर को इसकी जानकारी होनी चाहिए.
fdo_instrument_path कंपाइल, लिंक उस डायरेक्ट्री का पाथ जिसमें FDO इंस्ट्रूमेंटेशन प्रोफ़ाइल सेव की जाती है.
fdo_profile_path कंपाइल करें एफ़डीओ प्रोफ़ाइल का पाथ.
fdo_prefetch_hints_path कंपाइल करें कैश मेमोरी में प्रीफ़ेच की गई प्रोफ़ाइल का पाथ.
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 लिंकर के विकल्पों का इस्तेमाल करेगा. इससे बिल्ड तेज़ी से बढ़ता है, क्योंकि 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 ऑब्जेक्ट का इस्तेमाल करने की जानकारी होगी. जब भी पीआईसी कंपाइलेशन की ज़रूरत हो, तब `पिक` वैरिएबल मौजूद होता है. अगर यह सुविधा डिफ़ॉल्ट रूप से चालू नहीं है और `--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 जोड़ें, ताकि टूलचेन को ज़्यादा स्टैंडअलोन बनाया जा सके.