หน้านี้มุ่งเน้นที่การเขียนกฎที่ใช้ได้กับ Windows ปัญหาที่พบบ่อยในการ เขียนกฎแบบพกพา และโซลูชันบางอย่าง
เส้นทาง
ปัญหา
- ขีดจำกัดความยาว: ความยาวเส้นทางสูงสุดคือ 259 อักขระ - แม้ว่า Windows จะรองรับเส้นทางที่ยาวกว่า (สูงสุด 32767 อักขระ) แต่โปรแกรมจำนวนมากสร้างขึ้นโดยมี ขีดจำกัดที่ต่ำกว่า - โปรดทราบเกี่ยวกับโปรแกรมที่คุณเรียกใช้ในการดำเนินการ 
- ไดเรกทอรีการทำงาน: มีอักขระได้ไม่เกิน 259 ตัว - กระบวนการไม่สามารถ - cdลงในไดเรกทอรีที่มีความยาวเกิน 259 อักขระ
- การคำนึงถึงตัวพิมพ์เล็กหรือใหญ่: เส้นทาง Windows ไม่คำนึงถึงตัวพิมพ์เล็กหรือใหญ่ ส่วนเส้นทาง Unix คำนึงถึงตัวพิมพ์เล็กหรือใหญ่ - โปรดทราบถึงข้อจำกัดนี้เมื่อสร้างบรรทัดคำสั่งสำหรับการดำเนินการ 
- ตัวคั่นเส้นทาง: คือเครื่องหมายทับ ( - \`), not forward slash (/)- Bazel จัดเก็บเส้นทางในรูปแบบ Unix โดยใช้ตัวคั่น - /แม้ว่าโปรแกรม Windows บางโปรแกรมจะรองรับเส้นทางรูปแบบ Unix แต่โปรแกรมอื่นๆ ไม่รองรับ คำสั่งในตัวบางคำสั่งใน cmd.exe รองรับ แต่บางคำสั่งไม่รองรับ- คุณควรใช้ - \` separators on Windows: replace/- withเสมอเมื่อสร้างบรรทัดคำสั่งและตัวแปรสภาพแวดล้อมสำหรับการดำเนินการ
- เส้นทางแบบสัมบูรณ์: ไม่ขึ้นต้นด้วยเครื่องหมายทับ ( - /)- เส้นทางแบบสัมบูรณ์ใน Windows จะขึ้นต้นด้วยตัวอักษรของไดรฟ์ เช่น - C:\foo\bar.txtไม่มีรูทของระบบไฟล์เดียว- โปรดทราบว่าหากกฎตรวจสอบว่าเส้นทางเป็นแบบสัมบูรณ์หรือไม่ ควรหลีกเลี่ยงการใช้ Absolute Path เนื่องจากมักจะย้ายไม่ได้ 
วิธีแก้ไข:
- เส้นทางควรสั้น - หลีกเลี่ยงชื่อไดเรกทอรีที่ยาว โครงสร้างไดเรกทอรีที่ซ้อนกันลึก ชื่อไฟล์ที่ยาว ชื่อเวิร์กสเปซที่ยาว และชื่อเป้าหมายที่ยาว - ซึ่งทั้งหมดนี้อาจกลายเป็นคอมโพเนนต์เส้นทางของไฟล์อินพุตของการดำเนินการ และอาจทำให้ความยาวเส้นทางเกินขีดจำกัด 
- ใช้รูทเอาต์พุตแบบสั้น - ใช้แฟล็ก - --output_user_root=<path>เพื่อระบุเส้นทางแบบย่อสำหรับเอาต์พุตของ Bazel ขอแนะนำให้มีไดรฟ์ (หรือไดรฟ์เสมือน) สำหรับเอาต์พุตของ Bazel โดยเฉพาะ (เช่น ไฟล์- D:\`), and adding this line to your.bazelrc`)- build --output_user_root=D:/- หรือ - build --output_user_root=C:/_bzl
- ใช้ทางแยก - พูดอย่างคร่าวๆ[1] จังก์ชันคือลิงก์สัญลักษณ์ของไดเรกทอรี สร้าง Junction ได้ง่ายๆ และสามารถชี้ไปยังไดเรกทอรี (ในคอมพิวเตอร์เครื่องเดียวกัน) ที่มีเส้นทางยาว หากการดำเนินการบิลด์สร้าง จังก์ชันที่มีเส้นทางสั้นแต่มีเป้าหมายยาว เครื่องมือที่มีขีดจำกัดเส้นทางสั้นจะเข้าถึง ไฟล์ในไดเรกทอรีที่เชื่อมต่อได้ - ในไฟล์ - .batหรือใน cmd.exe คุณสามารถสร้าง Junction ได้ดังนี้- mklink /J c:\path\to\junction c:\path\to\very\long\target\path- [1]: พูดอย่างเคร่งครัด Junction ไม่ใช่ลิงก์สัญลักษณ์ แต่เพื่อ ประโยชน์ของการดำเนินการสร้าง คุณอาจถือว่า Junction เป็น Symlink ของไดเรกทอรี 
- แทนที่ - /ด้วย `` ในเส้นทางในการดำเนินการ / ตัวแปรสภาพแวดล้อม- เมื่อสร้างบรรทัดคำสั่งหรือตัวแปรสภาพแวดล้อมสำหรับการดำเนินการ ให้ใช้เส้นทางรูปแบบ 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(สคริปต์ชุดคำสั่ง)- โปรดทราบว่าสคริปต์เชลล์ ( - .sh) จะเรียกใช้ใน Windows ไม่ได้ คุณจึงระบุเป็น- ctx.actions.runของ- executableไม่ได้ นอกจากนี้ยังไม่มีสิทธิ์- +xที่ไฟล์จะมีได้ด้วย ดังนั้นคุณจึง เรียกใช้ไฟล์ใดก็ได้ไม่ได้เหมือนใน Linux
- คำสั่ง Bash: เพื่อให้พกพาได้ง่าย ให้หลีกเลี่ยงการเรียกใช้คำสั่ง Bash ในการดำเนินการโดยตรง - Bash มีการใช้งานอย่างแพร่หลายในระบบที่คล้าย Unix แต่โดยทั่วไปจะใช้ไม่ได้ใน Windows Bazel เองก็ พึ่งพา Bash (MSYS2) น้อยลงเรื่อยๆ ดังนั้นในอนาคตผู้ใช้ก็ไม่น่าจะต้องติดตั้ง MSYS2 พร้อมกับ Bazel หากต้องการให้ใช้กฎใน Windows ได้ง่ายขึ้น ให้หลีกเลี่ยงการเรียกใช้คำสั่ง Bash ใน การดำเนินการ 
- การจบบรรทัด: Windows ใช้ CRLF ( - \r\n) ส่วนระบบที่คล้าย Unix ใช้ LF (- \n)- โปรดทราบถึงข้อจำกัดนี้เมื่อเปรียบเทียบไฟล์ข้อความ โปรดคำนึงถึงการตั้งค่า Git โดยเฉพาะการสิ้นสุดบรรทัดเมื่อเช็คเอาต์หรือคอมมิต (ดู - core.autocrlfการตั้งค่าของ Git)
วิธีแก้ไข:
- ใช้กฎที่สร้างขึ้นโดยเฉพาะซึ่งไม่มี Bash - native.genrule()เป็น Wrapper สำหรับคำสั่ง Bash และมักใช้เพื่อแก้ปัญหาเล็กๆ น้อยๆ เช่น การคัดลอกไฟล์หรือการเขียนไฟล์ข้อความ คุณหลีกเลี่ยงการใช้ Bash (และไม่ต้องประดิษฐ์ล้อใหม่) ได้โดยดูว่า bazel-skylib มีกฎที่สร้างขึ้นเพื่อตอบสนองความต้องการของคุณหรือไม่ โดยไม่มีตัวใดที่ต้องใช้ Bash เมื่อสร้าง/ทดสอบใน Windows- ตัวอย่างกฎการสร้าง - copy_file()(source, documentation): คัดลอกไฟล์ไปยังที่อื่น และเลือกทำให้ไฟล์นั้นเรียกใช้งานได้
- write_file()(source, documentation): writes a text file, with the desired line endings (- auto,- unix, or- windows), optionally making it executable (if it's a script)
- run_binary()(source, documentation): เรียกใช้ไบนารี (หรือ- *_binaryrule) ด้วยอินพุตที่ระบุและเอาต์พุตที่คาดไว้เป็นการดำเนินการบิลด์ (นี่คือ Wrapper ของกฎบิลด์สำหรับ- ctx.actions.run)
- native_binary()(source, documentation): ห่อหุ้มไบนารีเนทีฟในกฎ- *_binaryซึ่งคุณสามารถ- bazel runหรือใช้ในแอตทริบิวต์- toolของ- run_binary()หรือแอตทริบิวต์- toolsของ- native.genrule()
 - ตัวอย่างกฎการทดสอบ - diff_test()(source, documentation): ทดสอบที่เปรียบเทียบเนื้อหาของไฟล์ 2 ไฟล์
- native_test()(source, documentation): wraps a native binary in a- *_testrule, which you can- bazel test
 
- ใน Windows ให้พิจารณาใช้สคริปต์ - .batสำหรับสิ่งเล็กๆ น้อยๆ- คุณสามารถใช้สคริปต์ - .batแทนสคริปต์- .shเพื่อแก้ปัญหางานเล็กๆ น้อยๆ ได้- เช่น หากคุณต้องการสคริปต์ที่ไม่ทำอะไรเลย หรือพิมพ์ข้อความ หรือออกด้วยรหัสข้อผิดพลาดที่กำหนดไว้ - .batไฟล์ธรรมดาก็เพียงพอแล้ว หากกฎแสดงผล- DefaultInfo()provider ฟิลด์- executableอาจอ้างอิงถึงไฟล์- .batนั้นใน Windows- และเนื่องจากนามสกุลไฟล์ไม่มีผลใน macOS และ Linux คุณจึงใช้ - .batเป็นนามสกุลได้เสมอ แม้แต่กับสคริปต์เชลล์- โปรดทราบว่าระบบจะเรียกใช้ไฟล์ - .batที่ว่างเปล่าไม่ได้ หากต้องการสคริปต์ที่ว่างเปล่า ให้เขียนช่องว่าง 1 ช่อง ในสคริปต์
- ใช้ Bash อย่างมีหลักการ - ในกฎการสร้างและการทดสอบ Starlark ให้ใช้ - ctx.actions.run_shellเพื่อเรียกใช้สคริปต์ Bash และคำสั่ง Bash เป็นการดำเนินการ- ในมาโคร Starlark ให้ห่อสคริปต์และคำสั่ง Bash ใน - native.sh_binary()หรือ- native.genrule()Bazel จะตรวจสอบว่า Bash พร้อมใช้งานหรือไม่ และเรียกใช้สคริปต์หรือคำสั่งผ่าน Bash- ในกฎของที่เก็บ Starlark ให้พยายามหลีกเลี่ยงการใช้ Bash โดยสิ้นเชิง ปัจจุบัน Bazel ยังไม่มีวิธีเรียกใช้คำสั่ง Bash ในกฎของที่เก็บในลักษณะที่เป็นไปตามหลักการ 
กำลังลบไฟล์
ปัญหา
- ลบไฟล์ขณะเปิดไม่ได้ - ระบบจะลบไฟล์ที่เปิดไม่ได้ (โดยค่าเริ่มต้น) และการพยายามลบจะทำให้เกิดข้อผิดพลาด "ปฏิเสธการเข้าถึง" หากลบไฟล์ไม่ได้ อาจเป็นเพราะกระบวนการที่กำลังทำงานยังคงเปิดไฟล์นั้นอยู่ 
- ลบไดเรกทอรีการทำงานของกระบวนการที่กำลังทำงานไม่ได้ - กระบวนการมีแฮนเดิลที่เปิดไปยังไดเรกทอรีการทำงาน และลบไดเรกทอรีไม่ได้ จนกว่ากระบวนการจะสิ้นสุด 
วิธีแก้ไข:
- ในโค้ด ให้ลองปิดไฟล์โดยเร็ว - ใน Java ให้ใช้ - try-with-resourcesใน Python ให้ใช้- with open(...) as f:ในทางทฤษฎี ให้พยายาม ปิดแฮนเดิลโดยเร็วที่สุด