इस पेज पर, Windows के साथ काम करने वाले नियम लिखने, एक से दूसरी जगह ले जाने लायक नियम लिखने में आने वाली आम समस्याओं, और उनके कुछ समाधानों के बारे में बताया गया है.
पथ
सवाल:
लंबाई की सीमा: पाथ की ज़्यादा से ज़्यादा लंबाई 259 वर्ण हो सकती है.
हालांकि Windows लंबे पाथ (32767 वर्णों तक) का भी समर्थन करता है, लेकिन कई प्रोग्राम कम से कम सीमा तय करें.
कार्रवाइयों में इस्तेमाल किए जाने वाले प्रोग्राम के बारे में ध्यान रखें.
वर्किंग डायरेक्ट्री: इसमें ज़्यादा से ज़्यादा 259 वर्ण हो सकते हैं.
प्रोसेस, 259 वर्णों से ज़्यादा लंबी डायरेक्ट्री में
cd
नहीं हो सकतीं.बड़े और छोटे अक्षरों में अंतर: Windows पाथ केस-इनसेंसिटिव होते हैं, जबकि Unix पाथ केस-सेंसिटिव होते हैं.
कार्रवाइयों के लिए कमांड लाइन बनाते समय इसका ध्यान रखें.
पाथ सेपरेटर: बैकस्लैश (
\`), not forward slash (
/`).बेज़ल,
/
सेपरेटर के साथ यूनिक्स-स्टाइल में बने पाथ स्टोर करता है. हालांकि, कुछ Windows प्रोग्राम यूनिक्स-स्टाइल पाथ, बाकी नहीं. cmd.exe में पहले से मौजूद कुछ निर्देश उनका समर्थन करते हैं, कुछ नहीं करते.ऐक्शन के लिए कमांडलाइन और एनवायरमेंट वैरिएबल बनाते समय, हमेशा
\` separators on Windows: replace
/with
` का इस्तेमाल करना सबसे अच्छा होता है.ऐब्सलूट पाथ: स्लैश (
/
) से शुरू न करें.Windows पर ऐब्सलूट पाथ, ड्राइव लेटर से शुरू होते हैं, जैसे कि
C:\foo\bar.txt
. फ़ाइल सिस्टम का कोई एक रूट नहीं होता.अगर आपका नियम यह जांच करता है कि कोई पाथ एब्सोल्यूट है या नहीं, तो इस बात का ध्यान रखें. ऐब्सलूट पाथ का इस्तेमाल नहीं किया जाना चाहिए, क्योंकि अक्सर वे पोर्टेबल नहीं होते.
समाधान:
पाथ छोटे रखें.
डायरेक्ट्री के लंबे नाम, डीप नेस्ट की गई डायरेक्ट्री स्ट्रक्चर, फ़ाइल के लंबे नाम, और लंबे फ़ाइल फ़ोल्डर का इस्तेमाल करने से बचें नाम, लंबे टारगेट नाम.
ये सभी, कार्रवाइयों के पाथ कॉम्पोनेंट बन सकते हैं' और हो सकता है कि पाथ की लंबाई खत्म हो जाए सीमा तय करें.
छोटे आउटपुट रूट का इस्तेमाल करें.
Baज़ल आउटपुट के लिए, एक छोटा पाथ तय करने के लिए,
--output_user_root=<path>
फ़्लैग का इस्तेमाल करें. अच्छा आइडिया सिर्फ़ बेज़ेल आउटपुट (जैसे किD:\`), and adding this line to your
.baज़ेनrc` फ़ाइल) के लिए ड्राइव (या वर्चुअल ड्राइव) मौजूद हो:build --output_user_root=D:/
या
build --output_user_root=C:/_bzl
जंक्शन का इस्तेमाल करना.
जंक्शन, डायरेक्ट्री के सिर्फ़ लिंक होते हैं[1]. जंक्शन आसानी से बनाए जा सकते हैं और ये एक ही कंप्यूटर पर, लंबे पाथ वाली डायरेक्ट्री पर ले जाते हैं. अगर कोई बिल्ड ऐक्शन ऐसा जंक्शन बनाता है जिसका पाथ छोटा है, लेकिन टारगेट लंबा है, तो छोटे पाथ की सीमा वाले टूल, जंक्शन की डायरेक्ट्री में मौजूद फ़ाइलों को ऐक्सेस कर सकते हैं.
.bat
फ़ाइलों या cmd.exe में, जंक्शन इस तरह बनाए जा सकते हैं:mklink /J c:\path\to\junction c:\path\to\very\long\target\path
[1]: सटीक तौर पर कहें, तो जंक्शन, सिंबल लिंक नहीं होते. हालांकि, बिल्ड ऐक्शन के लिए, जंक्शन को डायरेक्ट्री सिंबल लिंक माना जा सकता है.
कार्रवाइयों / एनवायरमेंट में पाथ में
/
को `` से बदलें.किसी कार्रवाई के लिए कमांड लाइन या एनवायरमेंट वैरिएबल बनाते समय, पाथ बनाएं Windows की शैली. उदाहरण:
def as_path(p, is_windows): if is_windows: return p.replace("/", "\\") else: return p
एनवायरमेंट वैरिएबल
समस्याएं:
केस-सेंसिटिविटी: Windows के एनवायरमेंट वैरिएबल के नाम केस-इनसेंसिटिव होते हैं.
उदाहरण के लिए, Java में
System.getenv("SystemRoot")
औरSystem.getenv("SYSTEMROOT")
से एक ही नतीजा मिलता है. (यह अन्य भाषाओं पर भी लागू होता है.)हर्मेटिकिटी: कार्रवाइयों में कम से कम कस्टम एनवायरमेंट वैरिएबल का इस्तेमाल होना चाहिए.
एनवायरमेंट वैरिएबल, ऐक्शन की कैश मेमोरी कुंजी का हिस्सा होते हैं. अगर किसी कार्रवाई में एनवायरमेंट वैरिएबल का इस्तेमाल किया जाता है जो अक्सर बदलते रहते हैं या उपयोगकर्ताओं के हिसाब से तय किए जाते हैं. इससे नियम कम कैश मेमोरी में सेव हो पाता है.
समाधान:
एनवायरमेंट वैरिएबल के नामों के लिए सिर्फ़ अपरकेस का इस्तेमाल करें.
यह सुविधा Windows, macOS, और Linux पर काम करती है.
कार्रवाई के एनवायरमेंट को कम करें.
ctx.actions.run
का इस्तेमाल करते समय, एनवायरमेंट कोctx.configuration.default_shell_env
पर सेट करें. अगर कार्रवाई के लिए और एनवायरमेंट वैरिएबल की ज़रूरत होती है, उन सभी को शब्दकोश में रखें और कार्रवाई के लिए भेजें. उदाहरण:load("@bazel_skylib//lib:dicts.bzl", "dicts") def _make_env(ctx, output_file, is_windows): out_path = output_file.path if is_windows: out_path = out_path.replace("/", "\\") return dicts.add(ctx.configuration.default_shell_env, {"MY_OUTPUT": out_path})
कार्रवाइयां
समस्याएं:
एक्ज़िक्यूट किए जा सकने वाले आउटपुट: हर एक्ज़ीक्यूटेबल फ़ाइल का एक एक्ज़ीक्यूटेबल एक्सटेंशन होना चाहिए.
सबसे सामान्य एक्सटेंशन हैं,
.exe
(बाइनरी फ़ाइलें) और.bat
(बैच स्क्रिप्ट).ध्यान रखें कि Windows पर शेल स्क्रिप्ट (
.sh
) एक्ज़ीक्यूटेबल नहीं होती हैं; आप उन्हें इस रूप में दर्ज नहीं कर सकतेctx.actions.run
काexecutable
. फ़ाइलों के लिए+x
अनुमति भी नहीं है. इसलिए, Linux की तरह अपनी पसंद की फ़ाइलें नहीं चलाई जा सकतीं.Bash कमांड: आसानी से इस्तेमाल करने के लिए, सीधे कार्रवाइयों में Bash कमांड चलाने से बचें.
Bash, Unix जैसे सिस्टम पर बहुत आम है. हालांकि, यह अक्सर Windows पर उपलब्ध नहीं होता. बेज़ल खुद हैं Bash (MSYS2) पर कम निर्भर करता है, इसलिए आने वाले समय में बेज़ल के साथ इंस्टॉल हो गया. Windows पर नियमों का आसानी से इस्तेमाल करने के लिए, Bash कमांड का इस्तेमाल कार्रवाइयां.
लाइन के आखिरी हिस्से: Windows, CRLF (
\r\n
) का इस्तेमाल करता है. Unix-जैसे सिस्टम LF (\n
) का इस्तेमाल करते हैं.टेक्स्ट फ़ाइलों की तुलना करते समय इसका ध्यान रखें. Git की सेटिंग का ध्यान रखें. खास तौर पर, चेक आउट या कमिट करते समय लाइन के आखिर में लगाए जाने वाले चिह्नों का ध्यान रखें. (Git की
core.autocrlf
सेटिंग देखें.)
समाधान:
बैश-लेस-बेस-मेड नियम का इस्तेमाल करें.
native.genrule()
, Bash कमांड के लिए एक रैपर है. इसका इस्तेमाल अक्सर सामान्य समस्याओं को हल करने के लिए किया जाता है जैसे कि कोई फ़ाइल कॉपी करना या टेक्स्ट फ़ाइल लिखना. Bash पर निर्भर रहने और फिर से पहिया बनाने से बचा जा सकता है: देखें कि bazel-skylib में आपकी ज़रूरतों के हिसाब से कोई नियम है या नहीं. इनमें से कोई भी बैश पर निर्भर नहीं है जब Windows पर बनाया/टेस्ट किया गया हो.नियम बनाने के उदाहरण:
copy_file()
(सोर्स, दस्तावेज़): फ़ाइल को कहीं और कॉपी करता है, वैकल्पिक रूप से उसे एक्ज़ीक्यूट करने लायक बनाता हैwrite_file()
(सोर्स, दस्तावेज़): पसंदीदा लाइन के अंत (auto
,unix
, याwindows
) वाली टेक्स्ट फ़ाइल लिखता है, वैकल्पिक रूप से इसे एक्ज़ीक्यूटेबल बनाया जा रहा है (अगर यह कोई स्क्रिप्ट है)run_binary()
(सोर्स, दस्तावेज़): बाइनरी (या*_binary
नियम) को दिए गए इनपुट और उम्मीद के मुताबिक आउटपुट के साथ, बिल्ड ऐक्शन के तौर पर चलाता है (यहctx.actions.run
के लिए बिल्ड नियम का रैपर है)native_binary()
(सोर्स, दस्तावेज़):*_binary
नियम में नेटिव बाइनरी को रैप करता है, जिसे आपbazel run
कर सकते हैं याrun_binary()
के नियम में इस्तेमाल कर सकते हैंtool
एट्रिब्यूट याnative.genrule()
काtools
एट्रिब्यूट
टेस्ट के नियम के उदाहरण:
Windows पर, छोटी-छोटी चीज़ों के लिए
.bat
स्क्रिप्ट का इस्तेमाल करें..sh
स्क्रिप्ट के बजाय,.bat
स्क्रिप्ट से छोटे-मोटे टास्क हल किए जा सकते हैं.उदाहरण के लिए, अगर आपको ऐसी स्क्रिप्ट चाहिए जो कुछ न करे, कोई मैसेज प्रिंट करे या किसी तय किए गए गड़बड़ी कोड के साथ बाहर निकले, तो एक साधारण
.bat
फ़ाइल काफ़ी होगी. अगर आपका नियम,DefaultInfo()
दिखाता है प्रोवाइडर के पास है, तोexecutable
फ़ील्ड Windows पर उस.bat
फ़ाइल का संदर्भ दे सकता है.macOS और Linux पर फ़ाइल एक्सटेंशन काम नहीं करते हैं. इसलिए,
.bat
को और शेल स्क्रिप्ट के लिए भी.ध्यान रखें कि खाली
.bat
फ़ाइलों को चलाया नहीं जा सकता. अगर आपको कोई खाली स्क्रिप्ट चाहिए, तो उसमें एक स्पेस लिखें.Bash का इस्तेमाल सही तरीके से करें.
Starlark के बिल्ड और टेस्ट नियमों में,
ctx.actions.run_shell
का इस्तेमाल करके Bash स्क्रिप्ट और Bash कमांड को कार्रवाइयों के तौर पर चलाएं.Starlark मैक्रो में, Bash स्क्रिप्ट और कमांड को
native.sh_binary()
याnative.genrule()
में रैप करें. Basel यह जांच करेगा कि Bash उपलब्ध है या नहीं. साथ ही, वह स्क्रिप्ट या कमांड को बैश.Starlark के डेटा स्टोर करने की जगह के नियमों में, बैश से बचने की कोशिश करें. फ़िलहाल, Bazel में कोई ऐसा तरीका नहीं है जिससे रीपॉज़िटरी के नियमों के मुताबिक, Bash कमांड चलाए जा सकें.
फ़ाइलें मिटाना
समस्याएं:
फ़ाइलों को खोलने के दौरान, मिटाया नहीं जा सकता.
खुली हुई फ़ाइलों को मिटाया नहीं जा सकता (डिफ़ॉल्ट रूप से), कोशिश करने पर "ऐक्सेस नहीं दिया गया" गड़बड़ियां हैं. अगर आप कोई फ़ाइल नहीं मिटा पा रहे हैं, तो हो सकता है कि किसी चल रही प्रोसेस में वह अब भी मौजूद हो खोलें.
चल रही प्रोसेस की वर्किंग डायरेक्ट्री को मिटाया नहीं जा सकता.
प्रोसेस के पास अपनी वर्किंग डायरेक्ट्री का खुला हैंडल होता है. प्रोसेस खत्म होने तक, डायरेक्ट्री को मिटाया नहीं जा सकता.
समाधान:
अपने कोड में, फ़ाइलों को तेज़ी से बंद करने की कोशिश करें.
Java में,
try-with-resources
का इस्तेमाल करें. Python में,with open(...) as f:
का इस्तेमाल करें. बुनियादी तौर पर, हैंडल बंद करने के लिए कहें.