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

समस्या की शिकायत करें सोर्स देखें Nightly · 8.4 · 8.3 · 8.2 · 8.1 · 8.0 · 7.6

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

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

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

"Make" शब्द का इस्तेमाल, इतिहास से जुड़ा है: इन वैरिएबल के सिंटैक्स और सिमैंटिक को मूल रूप से GNU Make से मैच करने के लिए बनाया गया था.

इस्तेमाल करें

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

my_attr = "prefix $(FOO) suffix"

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

my_attr = "prefix bar suffix"

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

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

my_attr = "prefix $@ suffix"

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

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

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

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

bazel info --show_make_env [build options]

इसके बाद, कैपिटल लेटर में लिखी गई आउटपुट की सबसे ऊपर वाली लाइनें देखें.

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

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

पाथ वैरिएबल

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

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

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

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

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

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

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

ये एट्रिब्यूट, खास तौर पर 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: आउटपुट डायरेक्ट्री. अगर outs में एक एंट्री है, तो यह उस फ़ाइल वाले डायरेक्ट्री में बदल जाता है. अगर इसमें एक से ज़्यादा एंट्री हैं, तो यह genfiles ट्री में पैकेज की रूट डायरेक्ट्री में फैल जाता है. भले ही, सभी आउटपुट फ़ाइलें एक ही सबडायरेक्ट्री में हों!

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

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

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

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

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

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

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

  • execpath: यह execroot के नीचे का पाथ दिखाता है. Bazel, इसी पाथ पर बिल्ड ऐक्शन चलाता है.

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

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

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

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

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

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

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

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

  • location: यह execpath या rootpath में से किसी एक का समानार्थी शब्द है. यह इस बात पर निर्भर करता है कि किस एट्रिब्यूट को बड़ा किया जा रहा है. यह Starlark से पहले की लेगसी सुविधा है. इसका इस्तेमाल तब तक न करें, जब तक आपको यह न पता हो कि यह किसी नियम के लिए क्या करती है. ज़्यादा जानकारी के लिए, #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"] सेट करता है कुछ नियम, जैसे कि java_binary, अपनी नियम की परिभाषा में C++ टूलचेन को शामिल करते हैं. ये वैरिएबल अपने-आप इनहेरिट हो जाते हैं.

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

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

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

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

  • CC_FLAGS: C/C++ कंपाइलर के लिए फ़्लैग का कम से कम सेट, ताकि genrules इनका इस्तेमाल कर सकें. खास तौर पर, इसमें ऐसे फ़्लैग होते हैं जिनकी मदद से सही आर्किटेक्चर चुना जा सकता है. ऐसा तब किया जाता है, जब CC कई आर्किटेक्चर के साथ काम करता हो.
  • NM: यह crosstool से "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") सेट करता है.

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

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

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

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

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

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