การใช้ Bazel บน Windows

หน้านี้ครอบคลุมแนวทางปฏิบัติแนะนำสำหรับการใช้ Bazel ใน Windows ดูวิธีการติดตั้งได้ที่ติดตั้ง Bazel ใน Windows

ปัญหาที่ทราบ

ปัญหาเกี่ยวกับ Bazel ใน Windows จะมีป้ายกำกับ "team-Windows" ใน GitHub คุณดูปัญหาที่ยังไม่ได้รับการแก้ไขได้ที่นี่

แนวทางปฏิบัติแนะนำ

หลีกเลี่ยงปัญหาเส้นทางยาว

เครื่องมือบางอย่างมีข้อจำกัดความยาวเส้นทางสูงสุดใน Windows ซึ่งรวมถึงคอมไพเลอร์ MSVC คุณระบุไดเรกทอรีเอาต์พุตแบบสั้นสำหรับ Bazel ได้โดยใช้แฟล็ก --output_user_root เพื่อหลีกเลี่ยงปัญหานี้

เช่น เพิ่มบรรทัดต่อไปนี้ลงในไฟล์ bazelrc

startup --output_user_root=C:/tmp

เปิดใช้การรองรับชื่อไฟล์ 8.3

Bazel พยายามสร้างชื่อย่อสำหรับเส้นทางไฟล์ที่ยาว แต่หากต้องการทำเช่นนั้น คุณต้องเปิดใช้การรองรับชื่อไฟล์ 8.3 สำหรับวอลุ่มที่มีไฟล์ที่มีเส้นทางยาว คุณเปิดใช้การสร้างชื่อ 8.3 ในทุกโวลุ่มได้โดยเรียกใช้คำสั่งต่อไปนี้

fsutil 8dot3name set 0

ฟีเจอร์บางอย่างกำหนดให้ Bazel ต้องสร้างลิงก์สัญลักษณ์ของไฟล์ใน Windows ได้ โดยการเปิดใช้โหมดนักพัฒนาแอป (ใน Windows 10 เวอร์ชัน 1703 ขึ้นไป) หรือโดยการเรียกใช้ Bazel ในฐานะผู้ดูแลระบบ ซึ่งจะช่วยให้คุณใช้ฟีเจอร์ต่อไปนี้ได้

เพิ่มบรรทัดต่อไปนี้ลงในไฟล์ bazelrc เพื่อให้ง่ายขึ้น

startup --windows_enable_symlinks
build --enable_runfiles

หมายเหตุ: การสร้าง Symlink ใน Windows เป็นการดำเนินการที่ใช้ทรัพยากรมาก โดยแฟล็ก --enable_runfiles อาจสร้างลิงก์สัญลักษณ์ของไฟล์จำนวนมาก โปรดเปิดใช้ฟีเจอร์นี้เมื่อจำเป็นเท่านั้น

การเรียกใช้ Bazel: เชลล์ MSYS2 เทียบกับพรอมต์คำสั่งเทียบกับ PowerShell

คำแนะนำ: เรียกใช้ Bazel จากพรอมต์คำสั่ง (cmd.exe) หรือจาก PowerShell

ตั้งแต่วันที่ 15-01-2020 เป็นต้นไป อย่าเรียกใช้ Bazel จาก bash ไม่ว่าจะเป็น จากเชลล์ MSYS2, Git Bash, Cygwin หรือ Bash รูปแบบอื่นๆ แม้ว่า Bazel อาจใช้ได้กับ Use Case ส่วนใหญ่ แต่ก็มีบางอย่างที่ใช้งานไม่ได้ เช่น การหยุดการสร้างด้วย Ctrl+C จาก MSYS2) นอกจากนี้ หากเลือกที่จะเรียกใช้ภายใต้ MSYS2 คุณจะต้องปิดใช้การแปลงเส้นทางอัตโนมัติของ MSYS2 มิฉะนั้น MSYS จะแปลงอาร์กิวเมนต์บรรทัดคำสั่ง ที่ดูเหมือนเส้นทาง Unix (เช่น //foo:bar) เป็นเส้นทาง Windows ดูรายละเอียดได้ที่คำตอบใน StackOverflow นี้

การใช้ Bazel โดยไม่ต้องใช้ Bash (MSYS2)

การใช้ Bazel Build โดยไม่ต้องใช้ Bash

Bazel เวอร์ชันก่อน 1.0 เคยกำหนดให้ใช้ Bash เพื่อสร้างกฎบางอย่าง

ตั้งแต่ Bazel 1.0 เป็นต้นไป คุณจะสร้างกฎใดก็ได้โดยไม่ต้องใช้ Bash เว้นแต่จะเป็นกฎต่อไปนี้

  • genrule เนื่องจาก genrules จะเรียกใช้คำสั่ง Bash
  • sh_binary หรือsh_test เนื่องจากต้องใช้ Bash โดยธรรมชาติ
  • กฎ Starlark ที่ใช้ ctx.actions.run_shell() หรือ ctx.resolve_command()

อย่างไรก็ตาม มักใช้ genrule สำหรับงานง่ายๆ เช่น การคัดลอกไฟล์ หรือการเขียนไฟล์ข้อความ คุณอาจพบกฎที่เหมาะสมในที่เก็บ bazel-skylib แทนการใช้ genrule (และขึ้นอยู่กับ Bash) เมื่อสร้างใน Windows กฎเหล่านี้ไม่จำเป็นต้องใช้ Bash

การใช้ bazel test โดยไม่ต้องใช้ Bash

Bazel เวอร์ชันก่อน 1.0 เคยต้องใช้ Bash เพื่อbazel test ทุกอย่าง

ตั้งแต่ Bazel 1.0 เป็นต้นไป คุณจะทดสอบกฎใดก็ได้โดยไม่ต้องใช้ Bash ยกเว้นในกรณีต่อไปนี้

  • คุณใช้ --run_under
  • กฎการทดสอบเองต้องใช้ Bash (เนื่องจากไฟล์ที่เรียกใช้งานได้เป็นสคริปต์เชลล์)

การใช้ bazel run โดยไม่ต้องใช้ Bash

Bazel เวอร์ชันก่อน 1.0 เคยต้องใช้ Bash เพื่อbazel run ทุกอย่าง

ตั้งแต่ Bazel 1.0 เป็นต้นไป คุณจะเรียกใช้กฎใดก็ได้โดยไม่ต้องใช้ Bash ยกเว้นในกรณีต่อไปนี้

  • คุณใช้ --run_under หรือ --script_path
  • กฎการทดสอบเองต้องใช้ Bash (เนื่องจากไฟล์ที่เรียกใช้งานได้เป็นสคริปต์เชลล์)

การใช้กฎ sh_binary และ sh_* รวมถึง ctx.actions.run_shell() โดยไม่มี Bash

คุณต้องใช้ Bash เพื่อสร้างและทดสอบsh_*กฎ รวมถึงสร้างและทดสอบกฎ Starlark ที่ใช้ ctx.actions.run_shell() และ ctx.resolve_command() ซึ่ง ไม่เพียงใช้กับกฎในโปรเจ็กต์เท่านั้น แต่ยังใช้กับกฎในที่เก็บข้อมูลภายนอก ที่โปรเจ็กต์ของคุณขึ้นอยู่กับ (แม้จะขึ้นอยู่กับแบบทรานซิทีฟ) ด้วย

ในอนาคตอาจมีตัวเลือกในการใช้ Windows Subsystem for Linux (WSL) เพื่อสร้างกฎเหล่านี้ แต่ในปัจจุบันยังไม่ใช่ลำดับความสำคัญสำหรับ ทีมย่อย Bazel บน Windows

การตั้งค่าตัวแปรสภาพแวดล้อม

ตัวแปรสภาพแวดล้อมที่คุณตั้งค่าในพรอมต์คำสั่งของ Windows (cmd.exe) จะตั้งค่าในเซสชันพรอมต์คำสั่งนั้นเท่านั้น หากเริ่ม cmd.exe ใหม่ คุณจะต้อง ตั้งค่าตัวแปรอีกครั้ง หากต้องการตั้งค่าตัวแปรเสมอเมื่อ cmd.exe เริ่มต้น คุณ สามารถเพิ่มตัวแปรเหล่านั้นลงในตัวแปรผู้ใช้หรือตัวแปรระบบในกล่องโต้ตอบ Control Panel > System Properties > Advanced > Environment Variables...

สร้างบน Windows

สร้าง C++ ด้วย MSVC

หากต้องการสร้างเป้าหมาย C++ ด้วย MSVC คุณต้องมีสิ่งต่อไปนี้

  • คอมไพเลอร์ Visual C++

  • (ไม่บังคับ) ตัวแปรสภาพแวดล้อม BAZEL_VC และ BAZEL_VC_FULL_VERSION

    Bazel จะตรวจหาคอมไพเลอร์ Visual C++ ในระบบโดยอัตโนมัติ หากต้องการบอก Bazel ให้ใช้การติดตั้ง VC ที่เฉพาะเจาะจง คุณสามารถตั้งค่าตัวแปรสภาพแวดล้อมต่อไปนี้

    สำหรับ Visual Studio 2017 และ 2019 ให้ตั้งค่าอย่างใดอย่างหนึ่งต่อไปนี้ BAZEL_VC นอกจากนี้ คุณยังตั้งค่าBAZEL_VC_FULL_VERSIONได้ด้วย

    • BAZEL_VC ไดเรกทอรีการติดตั้ง Visual C++ Build Tools

      set BAZEL_VC=C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC
      
    • BAZEL_VC_FULL_VERSION (ไม่บังคับ) เฉพาะ Visual Studio 2017 และ 2019 เวอร์ชันเต็ม หมายเลขของเครื่องมือสร้าง Visual C++ คุณเลือก Visual C++ Build Tools เวอร์ชันที่ต้องการได้ผ่าน BAZEL_VC_FULL_VERSION หากติดตั้งไว้มากกว่า 1 เวอร์ชัน ไม่เช่นนั้น Bazel จะเลือกเวอร์ชันล่าสุด

      set BAZEL_VC_FULL_VERSION=14.16.27023
      

    สำหรับ Visual Studio 2015 หรือเวอร์ชันเก่ากว่า ให้ตั้งค่า BAZEL_VC (ไม่รองรับ BAZEL_VC_FULL_VERSION)

    • BAZEL_VC ไดเรกทอรีการติดตั้ง Visual C++ Build Tools

      set BAZEL_VC=C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC
      
  • Windows SDK

    Windows SDK มีไฟล์ส่วนหัวและไลบรารีที่คุณต้องใช้เมื่อสร้าง แอปพลิเคชัน Windows ซึ่งรวมถึง Bazel เองด้วย โดยค่าเริ่มต้น ระบบจะใช้ Windows SDK เวอร์ชันล่าสุดที่ติดตั้ง นอกจากนี้ คุณยังระบุเวอร์ชัน Windows SDK ได้โดยการตั้งค่า BAZEL_WINSDK_FULL_VERSION คุณ สามารถใช้หมายเลข Windows 10 SDK แบบเต็ม เช่น 10.0.10240.0 หรือระบุ 8.1 เพื่อใช้ Windows 8.1 SDK (มี Windows 8.1 SDK เพียงเวอร์ชันเดียว) โปรดตรวจสอบว่าคุณได้ติดตั้ง Windows SDK ที่ระบุแล้ว

    ข้อกำหนด: รองรับ VC 2017 และ 2019 เครื่องมือบิลด์ VC 2015 แบบสแตนด์อโลนไม่รองรับการเลือก Windows SDK คุณจะต้องติดตั้ง Visual Studio 2015 แบบเต็ม ไม่เช่นนั้น BAZEL_WINSDK_FULL_VERSION จะถูกละเว้น

    set BAZEL_WINSDK_FULL_VERSION=10.0.10240.0
    

หากตั้งค่าทุกอย่างแล้ว คุณก็สร้างเป้าหมาย C++ ได้เลย

ลองสร้างเป้าหมายจากโปรเจ็กต์ ตัวอย่างของเรา

bazel build //examples/cpp:hello-world
bazel-bin\examples\cpp\hello-world.exe

โดยค่าเริ่มต้น ไบนารีที่สร้างขึ้นจะกำหนดเป้าหมายเป็นสถาปัตยกรรม x64 หากต้องการระบุสถาปัตยกรรมเป้าหมายอื่น ให้ตั้งค่า--cpuตัวเลือกการสร้างสำหรับสถาปัตยกรรมเป้าหมาย * x64 (ค่าเริ่มต้น): --cpu=x64_windows หรือไม่มีตัวเลือก * x86: --cpu=x64_x86_windows * ARM: --cpu=x64_arm_windows * ARM64: --cpu=arm64_windows

เช่น หากต้องการสร้างเป้าหมายสำหรับสถาปัตยกรรม ARM ให้เรียกใช้คำสั่งต่อไปนี้

bazel build //examples/cpp:hello-world --cpu=x64_arm_windows

หากต้องการสร้างและใช้ไลบรารีที่ลิงก์แบบไดนามิก (ไฟล์ DLL) โปรดดูตัวอย่างนี้

ขีดจำกัดความยาวของบรรทัดคำสั่ง: หากต้องการป้องกันปัญหาขีดจำกัดความยาวของบรรทัดคำสั่ง Windows ให้เปิดใช้ฟีเจอร์ไฟล์พารามิเตอร์ของคอมไพเลอร์ผ่าน --features=compiler_param_file

สร้าง C++ ด้วย Clang

ตั้งแต่เวอร์ชัน 0.29.0 เป็นต้นไป Bazel รองรับการสร้างด้วยไดรเวอร์คอมไพเลอร์ที่เข้ากันได้กับ MSVC ของ LLVM (clang-cl.exe)

ข้อกำหนด: หากต้องการสร้างด้วย Clang คุณต้องติดตั้ง ทั้ง LLVM และเครื่องมือสร้าง Visual C++ เนื่องจากแม้ว่าคุณจะใช้ clang-cl.exe เป็นคอมไพเลอร์ แต่คุณก็ยังต้องลิงก์กับ ไลบรารี Visual C++

Bazel สามารถตรวจหาการติดตั้ง LLVM ในระบบได้โดยอัตโนมัติ หรือคุณจะบอก Bazel อย่างชัดเจนว่า LLVM ติดตั้งอยู่ที่ใดโดยใช้ BAZEL_LLVM ก็ได้

  • BAZEL_LLVM ไดเรกทอรีการติดตั้ง LLVM

    set BAZEL_LLVM=C:\Program Files\LLVM

หากต้องการเปิดใช้เครื่องมือ Clang สำหรับการสร้าง C++ จะมีหลายกรณีดังนี้

  • ใน Bazel 0.28 และเวอร์ชันที่เก่ากว่า: ไม่รองรับ Clang

  • หากไม่มี --incompatible_enable_cc_toolchain_resolution: คุณสามารถเปิดใช้ Toolchain ของ Clang ได้โดยใช้แฟล็กบิลด์ --compiler=clang-cl

  • ด้วย --incompatible_enable_cc_toolchain_resolution: คุณต้องเพิ่มเป้าหมายแพลตฟอร์มลงใน BUILD file (เช่น ไฟล์ BUILD ระดับบนสุด):

    platform(
        name = "x64_windows-clang-cl",
        constraint_values = [
            "@platforms//cpu:x86_64",
            "@platforms//os:windows",
            "@bazel_tools//tools/cpp:clang-cl",
        ],
    )
    

    จากนั้นคุณจะเปิดใช้เครื่องมือเชน Clang ได้ด้วยวิธีใดวิธีหนึ่งต่อไปนี้

    • ระบุแฟล็กการสร้างต่อไปนี้
    --extra_toolchains=@local_config_cc//:cc-toolchain-x64_windows-clang-cl --extra_execution_platforms=//:x64_windows-clang-cl
    
    • ลงทะเบียนแพลตฟอร์มและเครื่องมือในไฟล์ MODULE.bazel ดังนี้
    register_execution_platforms(
        ":x64_windows-clang-cl"
    )
    
    register_toolchains(
        "@local_config_cc//:cc-toolchain-x64_windows-clang-cl",
    )
    

    เรามีแผนที่จะเปิดใช้แฟล็ก --incompatible_enable_cc_toolchain_resolution โดยค่าเริ่มต้นใน Bazel รุ่นต่อๆ ไป ดังนั้น เราขอแนะนำให้เปิดใช้การรองรับ Clang ด้วยวิธีที่ 2

สร้าง Java

หากต้องการสร้างเป้าหมาย Java คุณจะต้องมีสิ่งต่อไปนี้

ใน Windows, Bazel จะสร้างไฟล์เอาต์พุต 2 ไฟล์สำหรับกฎ java_binary ดังนี้

  • .jar ไฟล์
  • .exe ไฟล์ที่ตั้งค่าสภาพแวดล้อมสำหรับ JVM และเรียกใช้ไบนารีได้

ลองสร้างเป้าหมายจากโปรเจ็กต์ ตัวอย่างของเรา

  bazel build //examples/java-native/src/main/java/com/example/myproject:hello-world
  bazel-bin\examples\java-native\src\main\java\com\example\myproject\hello-world.exe

สร้าง Python

หากต้องการสร้างเป้าหมาย Python คุณจะต้องมีสิ่งต่อไปนี้

ใน Windows, Bazel จะสร้างไฟล์เอาต์พุต 2 ไฟล์สำหรับกฎ py_binary ดังนี้

  • ไฟล์ ZIP ที่แตกตัวเอง
  • ไฟล์ที่ดำเนินการได้ซึ่งสามารถเปิดตัวล่าม Python โดยมี ไฟล์ ZIP ที่แตกตัวเองได้เป็นอาร์กิวเมนต์

คุณจะเรียกใช้ไฟล์ปฏิบัติการ (มีนามสกุล .exe) หรือเรียกใช้ Python โดยใช้ไฟล์ ZIP ที่แตกตัวเองเป็นอาร์กิวเมนต์ก็ได้

ลองสร้างเป้าหมายจากโปรเจ็กต์ ตัวอย่างของเรา

  bazel build //examples/py_native:bin
  bazel-bin\examples\py_native\bin.exe
  python bazel-bin\examples\py_native\bin.zip

หากสนใจรายละเอียดเกี่ยวกับวิธีที่ Bazel สร้างเป้าหมาย Python ใน Windows โปรดดูเอกสาร การออกแบบนี้