"बनाएं" वैरिएबल

"बनाएं" वैरिएबल, बड़े किए जा सकने वाले स्ट्रिंग वैरिएबल की एक खास क्लास है. यह उन एट्रिब्यूट के लिए उपलब्ध होते हैं जिन्हें "'वैरिएबल बनाएं' में बदलाव करें" के तौर पर मार्क किया गया है.

उदाहरण के लिए, इनका इस्तेमाल उपयोगकर्ता के बनाए गए बिल्ड ऐक्शन में खास टूलचेन पाथ इंजेक्ट करने के लिए किया जा सकता है.

Bazel, पहले से तय वैरिएबल, दोनों उपलब्ध कराता है, जो सभी टारगेट के लिए उपलब्ध होते हैं. साथ ही, कस्टम वैरिएबल, जो डिपेंडेंसी टारगेट में तय किए जाते हैं और सिर्फ़ उन टारगेट के लिए उपलब्ध होते हैं जो इस पर निर्भर करते हैं.

"बनाएं" शब्द की वजह ऐतिहासिक है: इन वैरिएबल के सिंटैक्स और सिमैंटिक मूल रूप से GNU Make से मैच करने के लिए बने थे.

बिक्री और आय बढ़ाने के लिए,

"'वैरिएबल बनाएं' विकल्प के हिसाब से" के तौर पर मार्क किए गए एट्रिब्यूट, "बनाएं" वैरिएबल FOO का रेफ़रंस इस तरह दे सकते हैं:

my_attr = "prefix $(FOO) suffix"

दूसरे शब्दों में, $(FOO) से मेल खाने वाली कोई भी सबस्ट्रिंग, FOO की वैल्यू में बड़ी हो जाती है. अगर वैल्यू "bar" है, तो फ़ाइनल स्ट्रिंग यह बन जाती है:

my_attr = "prefix bar suffix"

अगर FOO, इस्तेमाल करने वाले टारगेट के लिए मालूम किसी वैरिएबल से मेल नहीं खाता, तो Bazel गड़बड़ी के साथ फ़ेल हो जाएगा.

"बनाएं" वैरिएबल के नाम में बिना अक्षर वाले चिह्न होते हैं, जैसे कि @. इन वैरिएबल का इस्तेमाल सिर्फ़ डॉलर चिह्न का इस्तेमाल करके किया जा सकता है. इसमें ब्रैकेट के बिना ऐसा किया जाता है. उदाहरण के लिए:

my_attr = "prefix $@ suffix"

$ को स्ट्रिंग लिटरल के तौर पर लिखने के लिए (जैसे कि वैरिएबल एक्सपैंशन को रोकने के लिए), $$ लिखें.

पहले से तय वैरिएबल

पहले से तय "बनाएं" वैरिएबल का रेफ़रंस किसी भी टारगेट पर, "'वैरिएबल बनाएं' में बदलाव करें" के तौर पर मार्क किए गए किसी भी एट्रिब्यूट से दिया जा सकता है.

बिल्ड के विकल्पों के दिए गए सेट के लिए, इन वैरिएबल की सूची और उनकी वैल्यू देखने के लिए,

bazel info --show_make_env [build options]

और कैपिटल लेटर वाली टॉप आउटपुट लाइन देखें.

पहले से तय वैरिएबल का उदाहरण देखें.

टूलचेन के विकल्प वैरिएबल

पाथ वैरिएबल

  • BINDIR: टारगेट आर्किटेक्चर के लिए जनरेट किए गए बाइनरी ट्री का आधार.

    ध्यान दें कि क्रॉस-कंपाइलिंग की सुविधा के लिए, होस्ट आर्किटेक्चर पर बिल्ड होने के दौरान चलने वाले प्रोग्राम के लिए, किसी दूसरे ट्री का इस्तेमाल किया जा सकता है.

    अगर आपको genrule में से कोई टूल चलाना है, तो उसका पाथ पाने के लिए, $(execpath toolname) का इस्तेमाल करने का सुझाव दिया जाता है. इसमें टूल का नाम, genrule के tools एट्रिब्यूट में शामिल होना चाहिए.

  • GENDIR: टारगेट आर्किटेक्चर के लिए जनरेट किए गए कोड ट्री का बेस.

मशीन आर्किटेक्चर वैरिएबल

  • TARGET_CPU: टारगेट आर्किटेक्चर का सीपीयू, जैसे कि k8.

पहले से तय जेनरूल वैरिएबल

ये एट्रिब्यूट खास तौर पर, genrule के cmd एट्रिब्यूट के लिए उपलब्ध होते हैं. आम तौर पर, ये एट्रिब्यूट सही तरीके से काम करने में मदद करते हैं.

पहले से तय जनरेट किए गए जेनरूल वैरिएबल का उदाहरण देखें.

  • OUTS: genrule की outs सूची. अगर आपके पास सिर्फ़ एक आउटपुट फ़ाइल है, तो $@ का भी इस्तेमाल किया जा सकता है.
  • SRCS: genrule की srcs सूची (या ज़्यादा सटीक तौर पर: srcs सूची में दिए गए लेबल से जुड़ी फ़ाइलों के पाथ के नाम). अगर आपके पास सिर्फ़ एक सोर्स फ़ाइल है, तो $< का भी इस्तेमाल किया जा सकता है.
  • <: SRCS, अगर यह एक ही फ़ाइल है. अन्य यूआरएल, बिल्ड की गड़बड़ी को ट्रिगर करता है.
  • @: OUTS, अगर यह एक ही फ़ाइल है. अन्य यूआरएल, बिल्ड की गड़बड़ी को ट्रिगर करता है.
  • RULEDIR: टारगेट की आउटपुट डायरेक्ट्री, यानी उस पैकेज के नाम से जुड़ी डायरेक्ट्री जिसमें genfiles या bin ट्री के तहत टारगेट शामिल है. //my/pkg:my_genrule के लिए, यह हमेशा my/pkg पर खत्म होता है. भले ही, //my/pkg:my_genrule के आउटपुट सबडायरेक्ट्री में हों.

  • @D: आउटपुट डायरेक्ट्री. अगर out में एक एंट्री है, तो यह उस फ़ाइल वाली डायरेक्ट्री में बड़ा हो जाता है. अगर इसमें एक से ज़्यादा एंट्री हैं, तो यह genfiles ट्री में पैकेज की रूट डायरेक्ट्री तक फैल जाती है, भले ही सभी आउटपुट फ़ाइलें एक ही सबडायरेक्ट्री में हो!

    ध्यान दें: @D के बजाय RULEDIR का इस्तेमाल करें, क्योंकि RULEDIR के सिमेंटिक शब्द आसान होते हैं. साथ ही, आउटपुट फ़ाइलों की संख्या चाहे जो भी हो, यह एक ही तरह से काम करता है.

    अगर जेनरूल को अस्थायी इंटरमीडिएट फ़ाइलें जनरेट करनी हों (शायद कंपाइलर जैसे किसी दूसरे टूल का इस्तेमाल करने की वजह से), तो उसे उन्हें @D पर लिखने की कोशिश करनी चाहिए (हालांकि, /tmp भी लिखा जा सकेगा). साथ ही, काम पूरा करने से पहले उन्हें हटा दें.

    खास तौर पर, ऐसी डायरेक्ट्री में न लिखें जिनमें इनपुट मौजूद हों. हो सकता है कि ये फ़ाइल सिस्टम, सिर्फ़ पढ़ने के लिए हों. भले ही, ऐसा न हो, लेकिन ऐसा करने से सोर्स ट्री ट्रैश हो जाएगा.

पहले से तय सोर्स/आउटपुट पाथ वैरिएबल

पहले से तय किए गए वैरिएबल execpath, execpaths, rootpath, rootpaths, location, और locations लेबल पैरामीटर (जैसे, $(execpath //foo:bar)) लेते हैं और उस लेबल से तय किए गए फ़ाइल पाथ की जगह ले लेते हैं.

सोर्स फ़ाइलों के लिए, यह आपके फ़ाइल फ़ोल्डर के रूट से जुड़ा पाथ है. नियमों के आउटपुट वाली फ़ाइलों के लिए, यह उस फ़ाइल का आउटपुट पाथ है. आउटपुट फ़ाइलों की जानकारी यहां देखें.

पहले से तय पाथ वैरिएबल का उदाहरण देखें.

  • execpath: यह उस एक्स्रूट के नीचे का पाथ दिखाता है जहां Bazel, बिल्ड ऐक्शन चलाता है.

    ऊपर दिए गए उदाहरण में, Bazel आपके फ़ाइल फ़ोल्डर रूट में मौजूद bazel-myproject सिमलिंक की मदद से लिंक की गई डायरेक्ट्री में, सभी बिल्ड ऐक्शन करता है. सोर्स फ़ाइल empty.source, पाथ bazel-myproject/testapp/empty.source से लिंक है. इसलिए, इसका exec पाथ (जो रूट के नीचे का सबपाथ है) testapp/empty.source है. फ़ाइल को खोजने के लिए, पाथ बिल्ड ऐक्शन का इस्तेमाल किया जा सकता है.

    आउटपुट फ़ाइलों को पहले की तरह ही प्रोसेस किया जाता है, लेकिन इनके साथ सबपाथ भी जोड़ा जाता है bazel-out/cpu-compilation_mode/bin (या टूल के आउटपुट के लिए: bazel-out/cpu-opt-exec-hash/bin). ऊपर दिए गए उदाहरण में, //testapp:app एक टूल है, क्योंकि यह show_app_output के tools एट्रिब्यूट में दिखता है. इसलिए, इसकी आउटपुट फ़ाइल app को bazel-myproject/bazel-out/cpu-opt-exec-hash/bin/testapp/app में लिखा जाता है. इस तरह एक्ज़ीक्यूट पाथ bazel-out/cpu-opt-exec-hash/bin/testapp/app है. इस अतिरिक्त प्रीफ़िक्स की मदद से, एक ही बिल्ड में दो अलग-अलग सीपीयू के लिए एक ही टारगेट बनाया जा सकता है. साथ ही, नतीजों को एक-दूसरे की नकल किए बिना प्रोसेस किया जा सकता है.

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

  • rootpath: यह उस पाथ के बारे में बताता है जिसका इस्तेमाल करके बनाई गई बाइनरी, रनटाइम के दौरान डिपेंडेंसी ढूंढने के लिए, मुख्य रिपॉज़िटरी से जुड़ी अपनी रनफ़ाइल डायरेक्ट्री की सबडायरेक्ट्री के तौर पर कोई डिपेंडेंसी ढूंढ सकती है. ध्यान दें: यह सुविधा सिर्फ़ तब काम करती है, जब --enable_runfiles चालू हो. हालांकि, Windows पर डिफ़ॉल्ट रूप से ऐसा नहीं होता. अलग-अलग प्लैटफ़ॉर्म पर सहायता पाने के लिए rlocationpath का इस्तेमाल करें.

    यह execpath की तरह है, लेकिन ऊपर बताए गए कॉन्फ़िगरेशन प्रीफ़िक्स को हटा देता है. ऊपर दिए गए उदाहरण में, इसका मतलब है कि empty.source और app, दोनों ही फ़ाइल फ़ोल्डर से जुड़े बिलकुल अलग पाथ का इस्तेमाल करते हैं: testapp/empty.source और testapp/app.

    किसी बाहरी रिपॉज़िटरी repo में किसी फ़ाइल का rootpath, ../repo/ से शुरू होगा. इसके बाद, रिपॉज़िटरी-रिलेटिव पाथ होगा.

    इसकी "सिर्फ़ एक आउटपुट" वाली ज़रूरी शर्तें execpath जैसी हैं.

  • rlocationpath: वह पाथ जिसे एक बनाने वाली बाइनरी फ़ाइल, रनफ़ाइल लाइब्रेरी के Rlocation फ़ंक्शन को पास कर सकती है, ताकि रनटाइम के दौरान कोई डिपेंडेंसी खोजी जा सके. इसके लिए रनफ़ाइल डायरेक्ट्री (अगर उपलब्ध हो) या रनफ़ाइल मेनिफ़ेस्ट का इस्तेमाल करें.

    यह rootpath से मिलता-जुलता है, क्योंकि इसमें कॉन्फ़िगरेशन प्रीफ़िक्स शामिल नहीं हैं. हालांकि, यह इस मामले में अलग होता है कि यह हमेशा रिपॉज़िटरी के नाम से शुरू होता है. ऊपर दिए गए उदाहरण में, इसका मतलब है कि empty.source और app इन पाथ के नतीजे देते हैं: myproject/testapp/empty.source और myproject/testapp/app.

    किसी बाहरी रिपॉज़िटरी repo में किसी फ़ाइल का rlocationpath, repo/ से शुरू होगा. इसके बाद, रिपॉज़िटरी-रिलेटिव पाथ होगा.

    रनटाइम के दौरान डिपेंडेंसी ढूंढने के लिए, इस पाथ को बाइनरी में पास करना और रनफ़ाइल लाइब्रेरी का इस्तेमाल करके, इसे फ़ाइल सिस्टम पाथ में ले जाना, बेहतर तरीका है. rootpath के मुकाबले, इसकी खासियत है कि यह सभी प्लैटफ़ॉर्म पर काम करती है. भले ही, रनफ़ाइल डायरेक्ट्री उपलब्ध न हो.

    इसकी "सिर्फ़ एक आउटपुट" वाली ज़रूरी शर्तें execpath जैसी हैं.

  • location: बड़े किए जा रहे एट्रिब्यूट के आधार पर, execpath या rootpath के लिए एक समानार्थी शब्द. यह स्टारलार्क के पहले किया जाने वाला व्यवहार है. इसका सुझाव तब तक नहीं दिया जाता, जब तक कि आपको वाकई पता न हो कि यह किसी खास नियम के लिए क्या करता है. ज़्यादा जानकारी के लिए, #2475 देखें.

execpaths, rootpaths, rlocationpaths, और locations क्रम से execpath, rootpath, rlocationpaths, औरlocation के बहुवचन वैरिएशन हैं. वे एक से ज़्यादा आउटपुट बनाने वाले लेबल के साथ काम करते हैं. इस मामले में, हर आउटपुट को एक स्पेस से अलग करके सूची में रखा जाता है. ज़ीरो-आउटपुट नियम और गलत लेबल की वजह से बिल्ड में गड़बड़ियां होती हैं.

रेफ़रंस के सभी लेबल, इस्तेमाल करने वाले टारगेट की srcs, आउटपुट फ़ाइलों या deps में दिखने चाहिए. ऐसा न करने पर, बिल्ड नहीं होता. C++ टारगेट, data में भी लेबल का रेफ़रंस दे सकते हैं.

लेबल को कैननिकल फ़ॉर्म में होना ज़रूरी नहीं है: foo, :foo, और //somepkg:foo सभी ठीक हैं.

कस्टम वैरिएबल

कस्टम "बनाएं" वैरिएबल को, "'वैरिएबल बनाएं' में बदलाव करें" के तौर पर मार्क किए गए किसी भी एट्रिब्यूट से रेफ़र किया जा सकता है. हालांकि, ऐसा सिर्फ़ उन टारगेट पर किया जा सकता है जो इन वैरिएबल को तय करने वाले अन्य टारगेट पर निर्भर करते हैं.

सबसे सही तरीका यह है कि सभी वैरिएबल को तब तक पसंद के मुताबिक बनाया जाना चाहिए, जब तक उन्हें कोर Bazel में बनाने की कोई वजह न हो. इससे, Bazel को संभावित रूप से महंगी डिपेंडेंसी से, टेरेट का इस्तेमाल करने वाले वैरिएबल की सप्लाई करने में मदद नहीं मिलती.

C++ टूलचेन वैरिएबल

नीचे दी गई जानकारी C++ टूलचेन नियमों में दी गई है. ये नियम toolchains = ["@bazel_tools//tools/cpp:current_cc_toolchain"] (या इसके बराबर के होस्ट टूलचेन के लिए "@bazel_tools//tools/cpp:current_cc_host_toolchain" ) को सेट करने वाले किसी भी नियम के लिए उपलब्ध होते हैं. java_binary जैसे कुछ नियम, अपने नियम की परिभाषा में साफ़ तौर पर C++ टूलचेन शामिल करते हैं. उन्हें ये वैरिएबल अपने-आप मिल जाते हैं.

पहले से मौजूद C++ नियम, "इस पर कंपाइलर चलाएं" की तुलना में ज़्यादा बेहतर हैं. कई प्लैटफ़ॉर्म पर तेज़ी से टेस्ट चलाने के साथ-साथ *SAN, ThinLTO , मॉड्यूल के साथ/के बिना, और सावधानी से ऑप्टिमाइज़ की गई बाइनरी को साथ में लागू करने के लिए, कंपाइलेशन मोड के साथ काम करने के लिए, पहले से मौजूद नियम काफ़ी हद तक यह पक्का करते हैं कि अंदरूनी तौर पर जनरेट की गई कई कार्रवाइयों पर सही इनपुट, आउटपुट, और कमांड लाइन फ़्लैग सेट किए गए हों.

ये वैरिएबल एक फ़ॉलबैक मैकेनिज़्म हैं. इनका इस्तेमाल, भाषा के विशेषज्ञ बहुत कम मामलों में करते हैं. अगर आपको भी यही प्लान पसंद हैं, तो कृपया पहले Bazel devs से संपर्क करें.

  • ABI: सी++ एबीआई वर्शन.
  • AR: क्रॉसटूल से "ar" कमांड.
  • C_COMPILER: C/C++ कंपाइलर आइडेंटिफ़ायर, उदाहरण के लिए, llvm.
  • CC: C और C++ कंपाइलर कमांड.

    हमारा सुझाव है कि आप हमेशा CC के साथ CC_FLAGS का इस्तेमाल करें. अपने जोखिम पर ऐसा नहीं कर पाएंगे.

  • CC_FLAGS: C/C++ कंपाइलर के लिए फ़्लैग का कम से कम सेट, जिसका इस्तेमाल जेन रूल के लिए किया जा सकता है. खास तौर पर, अगर CC एक से ज़्यादा आर्किटेक्चर के साथ काम करता है, तो सही आर्किटेक्चर को चुनने के लिए फ़्लैग शामिल होते हैं.
  • NM: क्रॉसटूल से "nm" कमांड.
  • OBJCOPY: C/C++ कंपाइलर के साथ एक ही सुइट का ऑब्जकॉपी कमांड.
  • STRIP: C/C++ कंपाइलर वाले उसी सुइट का स्ट्रिप कमांड.

Java टूलचेन वैरिएबल

नीचे दी गई जानकारी Java टूलचेन के नियमों में बताई गई है और ये उन सभी नियमों के लिए उपलब्ध हैं जो toolchains = ["@bazel_tools//tools/jdk:current_java_runtime"] या होस्ट टूलचेन के बराबर के होस्ट टूलचेन के लिए "@bazel_tools//tools/jdk:current_host_java_runtime" को सेट करते हैं.

जेडीके के ज़्यादातर टूल का इस्तेमाल सीधे तौर पर नहीं किया जाना चाहिए. पहले से मौजूद Java नियमों में, Java को कंपाइल करने और पैकेजिंग के लिए, अपस्ट्रीम टूल के मुकाबले ज़्यादा बेहतर तरीकों का इस्तेमाल किया जाता है. जैसे, इंटरफ़ेस Jars, हेडर इंटरफ़ेस Jars, और बेहतर तरीके से ऑप्टिमाइज़ की गई Jar पैकेजिंग और मर्जिंग को लागू करना.

ये वैरिएबल एक फ़ॉलबैक मैकेनिज़्म हैं. इनका इस्तेमाल, भाषा के विशेषज्ञ बहुत कम मामलों में करते हैं. अगर आपको भी यही प्लान पसंद हैं, तो कृपया पहले Bazel devs से संपर्क करें.

  • JAVA: "java" कमांड (एक Java वर्चुअल मशीन). इससे बचें और जहां तक हो सके java_binary नियम का इस्तेमाल करें. यह काफ़ी मिलता-जुलता पाथ हो सकता है. अगर आपको java को शुरू करने से पहले डायरेक्ट्री बदलनी ज़रूरी है, तो आपको इसे बदलने से पहले, काम करने वाली डायरेक्ट्री को कैप्चर करना होगा.
  • JAVABASE: वह बेस डायरेक्ट्री जिसमें Java की सुविधाएं होती हैं. यह काफ़ी मिलता-जुलता पाथ हो सकता है. इसमें एक "bin" सबडायरेक्ट्री होगी.

Starlark से तय किए गए वैरिएबल

नियम और टूलचेन लिखने वाले, पूरी तरह से कस्टम वैरिएबल तय कर सकते हैं. ऐसा करने के लिए, उन्हें TemplateVariableInfo प्रोवाइडर को दिखाया जा सकता है. इसके बाद, toolchains एट्रिब्यूट की मदद से, इन नियमों के आधार पर कोई भी नियम उनकी वैल्यू पढ़ सकता है:

Starlark से तय किए गए वैरिएबल का उदाहरण देखें.