इस पेज पर, Windows के साथ काम करने वाले नियम लिखने, एक से दूसरी जगह ले जाने लायक नियम लिखने में आने वाली आम समस्याओं, और उनके कुछ समाधानों के बारे में बताया गया है.
पथ
सवाल:
लंबाई की सीमा: पाथ में ज़्यादा से ज़्यादा 259 वर्ण हो सकते हैं.
हालांकि, Windows में 32,767 वर्णों तक के लंबे पाथ का इस्तेमाल किया जा सकता है, लेकिन कई प्रोग्राम कम वर्णों के साथ बनाए जाते हैं.
कार्रवाइयों में चलाए जाने वाले प्रोग्राम के बारे में इस बात का ध्यान रखें.
वर्किंग डायरेक्ट्री: इसमें भी 259 से ज़्यादा वर्ण इस्तेमाल नहीं किए जा सकते.
प्रक्रियाओं से जुड़ी डायरेक्ट्री में
cd
, 259 से ज़्यादा वर्ण नहीं हो सकते.केस-सेंसिटिविटी: Windows के पाथ, केस-इनसेंसिटिव होते हैं. साथ ही, यूनिक्स पाथ केस-सेंसिटिव होते हैं.
कार्रवाइयों के लिए कमांड लाइन बनाते समय इसका ध्यान रखें.
पाथ सेपरेटर: बैकस्लैश (
\`), not forward slash (
/`) होते हैं.बेज़ल,
/
सेपरेटर के साथ यूनिक्स-स्टाइल में बने पाथ स्टोर करता है. हालांकि, कुछ Windows प्रोग्राम में यूनिक्स स्टाइल के पाथ काम करते हैं, लेकिन कुछ में नहीं. cmd.exe में पहले से मौजूद कुछ निर्देशों के साथ, ये फ़ंक्शन काम करते हैं, जबकि कुछ के साथ नहीं.बेहतर होगा कि जब आप कोई निर्देश दें, तो हमेशा
\` separators on Windows: replace
/with
` का इस्तेमाल करें कार्रवाइयों के लिए लाइनें और एनवायरमेंट वैरिएबल.एब्सोलूट पाथ: स्लैश (
/
) से शुरू न करें.Windows पर एब्सोल्यूट पाथ, ड्राइव लेटर से शुरू होते हैं, जैसे कि
C:\foo\bar.txt
. कोई सिंगल नहीं फ़ाइल सिस्टम रूट शामिल है.अगर आपका नियम यह जांच करता है कि कोई पाथ एब्सोल्यूट है या नहीं, तो इस बात का ध्यान रखें. ऐब्सलूट पाथ ऐसा नहीं करना चाहिए, क्योंकि आम तौर पर इन्हें एक जगह से दूसरी जगह नहीं रखा जा सकता.
समाधान:
पाथ को छोटा रखें.
डायरेक्ट्री के लंबे नाम, डीप नेस्ट की गई डायरेक्ट्री स्ट्रक्चर, फ़ाइल के लंबे नाम, और लंबे फ़ाइल फ़ोल्डर का इस्तेमाल करने से बचें नाम, लंबे टारगेट नाम.
ये सभी, कार्रवाइयों के पाथ कॉम्पोनेंट बन सकते हैं' और हो सकता है कि पाथ की लंबाई खत्म हो जाए सीमा तय करें.
छोटे आउटपुट रूट का इस्तेमाल करें.
Bazel के आउटपुट के लिए छोटा पाथ तय करने के लिए,
--output_user_root=<path>
फ़्लैग का इस्तेमाल करें. Bazel के आउटपुट (जैसे किD:\`), and adding this line to your
.bazelrc` फ़ाइल) के लिए, एक ड्राइव (या वर्चुअल ड्राइव) बनाना एक अच्छा आइडिया है: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]: सटीक तौर पर कहें, तो जंक्शन, सिंबल लिंक नहीं होते. हालांकि, बिल्ड ऐक्शन के लिए, जंक्शन को डायरेक्ट्री सिंबल लिंक माना जा सकता है.
कार्रवाइयों / envvars में पाथ में
/
को `` से बदलें.किसी कार्रवाई के लिए कमांड लाइन या एनवायरमेंट वैरिएबल बनाते समय, पाथ को 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 गेम, Unix जैसे सिस्टम पर बड़े पैमाने पर उपलब्ध है. हालांकि, यह Windows पर अक्सर उपलब्ध नहीं होता. बेज़ल खुद हैं Bash (MSYS2) पर कम निर्भर करता है, इसलिए आने वाले समय में बेज़ल के साथ इंस्टॉल हो गया. Windows पर नियमों को आसानी से इस्तेमाल करने के लिए, ऐक्शन में Bash कमांड चलाने से बचें.
लाइन के आखिरी हिस्से: Windows, CRLF (
\r\n
) का इस्तेमाल करता है. Unix-जैसे सिस्टम LF (\n
) का इस्तेमाल करते हैं.टेक्स्ट फ़ाइलों की तुलना करते समय, इस बात का ध्यान रखें. Git की सेटिंग का ध्यान रखें. खास तौर पर, चेक आउट या कमिट करते समय लाइन के आखिर में लगाए जाने वाले चिह्नों का ध्यान रखें. (Git की
core.autocrlf
सेटिंग देखें.)
समाधान:
अपने काम के हिसाब से बनाए गए Bash-less नियम का इस्तेमाल करें.
native.genrule()
, Bash निर्देशों के लिए एक रैपर है. इसका इस्तेमाल अक्सर आसान समस्याओं को हल करने के लिए किया जाता है. जैसे, किसी फ़ाइल को कॉपी करना या टेक्स्ट फ़ाइल लिखना. Bash पर भरोसा करने से बचें और व्हील): देखें कि क्या baaz-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
फ़ाइलों को चलाया नहीं जा सकता. अगर आपको कोई खाली स्क्रिप्ट चाहिए, तो उसमें एक स्पेस लिखें.बैश का इस्तेमाल सैद्धांतिक तरीके से करें.
Starlark के बिल्ड और टेस्ट नियमों में,
ctx.actions.run_shell
का इस्तेमाल करके Bash स्क्रिप्ट और Bash कमांड को कार्रवाइयों के तौर पर चलाएं.Starlark मैक्रो में, Bash स्क्रिप्ट और कमांड को
native.sh_binary()
याnative.genrule()
. Basel यह जांच करेगा कि Bash उपलब्ध है या नहीं. साथ ही, वह स्क्रिप्ट या कमांड को बैश.Starlark के डेटा स्टोर करने की जगह के नियमों में, बैश से बचने की कोशिश करें. फ़िलहाल, Basel में दौड़ने का कोई तरीका नहीं है डेटा स्टोर करने के नियमों में बैश कमांड को सैद्धांतिक तरीके से इस्तेमाल करें.
फ़ाइलें मिटाना
समस्याएं:
फ़ाइलें खुली होने पर उन्हें मिटाया नहीं जा सकता.
खुली हुई फ़ाइलों को मिटाया नहीं जा सकता (डिफ़ॉल्ट रूप से), कोशिश करने पर "ऐक्सेस नहीं दिया गया" गड़बड़ियां हैं. अगर आप कोई फ़ाइल नहीं मिटा पा रहे हैं, तो हो सकता है कि किसी चल रही प्रोसेस में वह अब भी मौजूद हो खोलें.
चल रही प्रोसेस की वर्किंग डायरेक्ट्री को मिटाया नहीं जा सकता.
प्रोसेस के पास अपनी वर्किंग डायरेक्ट्री का खुला हैंडल होता है. प्रोसेस खत्म होने तक, डायरेक्ट्री को मिटाया नहीं जा सकता.
समाधान:
अपने कोड में, फ़ाइलों को जल्द से जल्द बंद करने की कोशिश करें.
Java में,
try-with-resources
का इस्तेमाल करें. Python में,with open(...) as f:
का इस्तेमाल करें. आम तौर पर, हैंडल को जल्द से जल्द बंद करने की कोशिश करें.