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