तारीख सेव करें: BazelCon 2023, 24 से 25 अक्टूबर तक Google म्यूनिख में होगा! ज़्यादा जानें

Windows पर लिखने के नियम

किसी समस्या की शिकायत करें स्रोत देखें

इस पेज में, Windows के साथ काम करने वाले नियमों को लिखने और पोर्टेबल नियमों को लिखने से जुड़ी आम समस्याओं के बारे में बताया गया है.

पथ

समस्याएं:

  • लंबाई की सीमा: पाथ की अधिकतम लंबाई 259 वर्ण होती है.

    हालांकि, Windows पर लंबे पाथ (ज़्यादा से ज़्यादा 3,2767 वर्ण) काम करते हैं, लेकिन कई प्रोग्राम में तय सीमा से कम पेज बनाए गए हैं.

    कार्रवाइयों में चलाए जाने वाले प्रोग्राम के बारे में ध्यान रखें.

  • वर्किंग डायरेक्ट्री: इसमें ज़्यादा से ज़्यादा 259 वर्ण हो सकते हैं.

    प्रक्रियाओं में 259 से ज़्यादा वर्णों वाली निर्देशिका में cd नहीं हो सकता.

  • केस-सेंसिटिव (बड़े और छोटे अक्षरों में अंतर): Windows पाथ, केस-इनसेंसिटिव होते हैं, Unix पाथ केस-सेंसिटिव (बड़े और छोटे अक्षरों में अंतर) होते हैं.

    कार्रवाइयों के लिए कमांड लाइन बनाते समय इस बात का ध्यान रखें.

  • पाथ विभाजक: बैकस्लैश (\`), not forward slash (/`).

    Bazel, Unix-style वाले पाथ को / सेपरेटर से स्टोर करता है. हालांकि, Windows के कुछ प्रोग्राम में, Unix-स्टाइल वाले पाथ का इस्तेमाल किया जा सकता है, जबकि दूसरों के पास नहीं. cmd.exe में पहले से मौजूद कुछ निर्देश उनका समर्थन करते हैं, कुछ नहीं.

    कार्रवाइयों के लिए कमांड लाइन और एनवायरमेंट वैरिएबल बनाते समय, हमेशा \` separators on Windows: replace/with का इस्तेमाल करना सबसे अच्छा होता है.

  • निरपेक्ष पाथ: स्लैश (/) से शुरू नहीं होते.

    Windows के सभी पाथ, Drive के अक्षर से शुरू होते हैं, जैसे कि 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 (बैच स्क्रिप्ट) हैं.

    ध्यान रखें कि शेल स्क्रिप्ट (.sh) Windows पर एक्ज़ीक्यूटेबल नहीं हैं; आप उन्हें ctx.actions.run के executable के तौर पर तय नहीं कर सकते. फ़ाइलों के पास +x की अनुमति भी नहीं होती है. इसलिए, आप Linux जैसी आर्बिट्रेरी फ़ाइलें नहीं चला सकते.

  • बैश कमांड: पोर्टेबिलिटी के लिए, ऐक्शन में बैश कमांड चलाने से बचें.

    यूनिक्स जैसे सिस्टम पर बैश बड़े पैमाने पर मौजूद है, लेकिन यह अक्सर Windows पर मौजूद नहीं होता. Bazel, Bash (MSYS2) पर कम और कम निर्भर हो रहा है. इसलिए, आने वाले समय में यह संभावना होगी कि उपयोगकर्ताओं को Bazel के साथ MSYS2 को इंस्टॉल करने की ज़रूरत पड़ेगी. Windows पर नियमों को आसानी से इस्तेमाल करने के लिए, ऐक्शन में Bash कमांड चलाने से बचें.

  • लाइन के आखिरी हिस्से: Windows, CRLF (\r\n) का इस्तेमाल करता है, Unix जैसे सिस्टम LF (\n) का इस्तेमाल करते हैं.

    टेक्स्ट फ़ाइलों की तुलना करते समय सावधानी बरतें. Git सेटिंग के बारे में सजग रहें. खास तौर पर, चेकआउट या तय करते समय लाइन एंडिंग पर ध्यान दें. (GitHub की core.autocrlf सेटिंग देखें.)

समाधान:

  • बेश-फ़्री तरीके से बनाए गए नियम का इस्तेमाल करें.

    बैश कमांड के लिए, native.genrule() एक रैपर है. आम तौर पर, इसका इस्तेमाल किसी फ़ाइल को कॉपी करने या टेक्स्ट फ़ाइल लिखने जैसी सामान्य समस्याओं को हल करने के लिए किया जाता है. आप बैश पर भरोसा करने (और व्हील को नया रूप देने) से बच सकते हैं: देखें कि क्या bazel-skylib ने अपनी ज़रूरतों के लिए एक नियम बनाया है. इनमें से कोई भी Windows पर बनाए गए/टेस्ट किए गए Bash पर निर्भर नहीं करता है.

    नियम बनाने के उदाहरण:

    • copy_file() (सोर्स, दस्तावेज़): फ़ाइल को किसी दूसरी जगह पर कॉपी करके, उसे एक्ज़ीक्यूटेबल बनाता है

    • write_file() (सोर्स, दस्तावेज़): इस टेक्स्ट लाइन को अपनी पसंद की लाइन के आखिरी हिस्से (auto, unix या windows) के साथ लिखा जा सकता है, अगर यह स्क्रिप्ट हो, तो विकल्प के तौर पर देता है

    • run_binary() (स्रोत, दस्तावेज़): बिल्ड कार्रवाई के रूप में, दिए गए इनपुट और अपेक्षित आउटपुट के साथ एक बाइनरी (या *_binary नियम) चलाता है (ctx.actions.run के लिए यह एक बिल्ड नियम रैपर है)

    • native_binary() (सोर्स, दस्तावेज़): यह, *_binary नियम में नेटिव बाइनरी को रैप करता है. इसे run_binary() केtool एट्रिब्यूट या native.genrule() के tools एट्रिब्यूट में इस्तेमाल किया जा सकता है

    टेस्ट के नियम के उदाहरण:

    • diff_test() (सोर्स, दस्तावेज़): यह जांच, जो दो फ़ाइलों के कॉन्टेंट की तुलना करती है

    • native_test() (सोर्स, दस्तावेज़): यह *_test नियम में नेटिव बाइनरी को रैप करता है. इसे आप bazel test पर सेट कर सकते हैं

  • Windows पर कम चीज़ों के लिए, .bat स्क्रिप्ट का इस्तेमाल करें.

    .bat स्क्रिप्ट की मदद से छोटे टास्क पूरे किए जा सकते हैं. इसके लिए, आपको .sh स्क्रिप्ट का इस्तेमाल करना होगा.

    उदाहरण के लिए, अगर आपको कोई ऐसी स्क्रिप्ट चाहिए जो कुछ नहीं करती है या कोई मैसेज प्रिंट करती है या फ़िक्स कोड के साथ एग्ज़िट करती है, तो .bat फ़ाइल काफ़ी होगी. अगर आपका नियम DefaultInfo() की सेवा देने वाली कंपनी को रिटर्न करता है, तो हो सकता है कि executable फ़ील्ड, Windows पर उस .bat फ़ाइल का रेफ़रंस दे.

    साथ ही, फ़ाइल एक्सटेंशन, macOS और Linux के लिए काम के नहीं होते हैं. इसलिए, एक्सटेंशन के तौर पर, .bat इस्तेमाल किया जा सकता है. भले ही, शेल स्क्रिप्ट हों.

    इस बात का ध्यान रखें कि .bat खाली फ़ाइलों को एक्ज़ीक्यूट नहीं किया जा सकता. अगर आपको किसी खाली स्क्रिप्ट की ज़रूरत है, तो उसमें एक स्पेस लिखें.

  • बैश का इस्तेमाल प्रिंसिपल तरीके से करें.

    Starlark के बिल्ड और टेस्ट नियमों में, ctx.actions.run_shell का इस्तेमाल करके Bash स्क्रिप्ट और Bash कमांड को ऐक्शन के तौर पर चलाएं.

    Starlark मैक्रो में, native.sh_binary() या native.genrule() में Bash स्क्रिप्ट और निर्देशों को रैप करें. बैज़ल यह जांच करेगा कि क्या बैश उपलब्ध है और वह Bash के ज़रिए स्क्रिप्ट या निर्देश चलाएगा.

    Starlark डेटा स्टोर करने की जगह के नियमों में, पूरी तरह से Bash से बचें. फ़िलहाल, Bazel में डेटा को स्टोर करने के नियमों में, सिद्धांत के तौर पर बैश कमांड का इस्तेमाल करने की सुविधा नहीं है.

फ़ाइलें मिटाना

समस्याएं:

  • फ़ाइलें खुली होने के दौरान मिटाई नहीं जा सकतीं.

    खुली हुई फ़ाइलों को मिटाया नहीं जा सकता (डिफ़ॉल्ट रूप से), गड़बड़ी की वजह से "ऐक्सेस नहीं दिया जा सकता" वाली गड़बड़ी दिखती है. अगर आप फ़ाइल को नहीं मिटा सकते, तो हो सकता है कि प्रोसेस चल रही हो.

  • चल रही प्रोसेस की डायरेक्ट्री को मिटाया नहीं जा सकता.

    प्रोसेस के पास अपनी काम करने वाली डायरेक्ट्री के लिए एक ओपन हैंडल होता है. जब तक प्रोसेस खत्म नहीं हो जाती, तब तक डायरेक्ट्री को मिटाया नहीं जा सकता.

समाधान:

  • अपने कोड में, फ़ाइलों को जल्द से जल्द बंद करने की कोशिश करें.

    Java में, try-with-resources का इस्तेमाल करें. Python में, with open(...) as f: का इस्तेमाल करें. असल में, जितनी जल्दी हो सके हैंडल को बंद करके देखें.