การใช้ Bazel บน Windows

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

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

ปัญหาเกี่ยวกับ Bazel ที่เกี่ยวข้องกับ Windows จะมีป้ายกำกับ "area-Windows" ใน GitHub GitHub-Windows

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

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

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

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

startup --output_user_root=C:/tmp

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

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

startup --windows_enable_symlinks

build --enable_runfiles

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

การเรียกใช้ Bazel: เชลล์ MSYS2, Command Prompt หรือ PowerShell

คำแนะนำ: เรียกใช้ Bazel จาก Command Prompt (cmd.exe) หรือจาก PowerShell

ตั้งแต่วันที่ 15 มกราคม 2020 เป็นต้นมา ห้าม เรียกใช้ Bazel จาก bash ไม่ว่าจะเป็น จากเชลล์ MSYS2, Git Bash, Cygwin หรือ Bash เวอร์ชันอื่นๆ แม้ว่า Bazel อาจทำงานได้ในกรณีการใช้งานส่วนใหญ่ แต่บางอย่างก็ใช้งานไม่ได้ เช่น การขัดจังหวะบิลด์ด้วย 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 เนื่องจาก genrule จะเรียกใช้คำสั่ง Bash
  • กฎ sh_binary หรือ sh_test เนื่องจากกฎเหล่านี้จำเป็นต้องใช้ Bash
  • กฎ Starlark ที่ใช้ ctx.actions.run_shell() หรือ ctx.resolve_command()

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

การใช้ bazel test โดยไม่มี Bash

Bazel เวอร์ชันก่อน 1.0 กำหนดให้ต้องใช้ Bash ในการ bazel test ทุกอย่าง

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

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

การใช้ bazel run โดยไม่มี Bash

Bazel เวอร์ชันก่อน 1.0 กำหนดให้ต้องใช้ Bash ในการ bazel run ทุกอย่าง

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

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

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

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

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

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

ตัวแปรสภาพแวดล้อมที่คุณตั้งค่าใน Command Prompt ของ Windows (cmd.exe) จะตั้งค่าไว้ในเซสชัน Command Prompt นั้นเท่านั้น หากคุณเริ่ม 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++ Build Tools คุณสามารถเลือกเวอร์ชัน 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
      
  • The 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 Build Tools แบบสแตนด์อโลนไม่รองรับการเลือก 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 หากต้องการสร้างสำหรับสถาปัตยกรรม ARM64 ให้ใช้คำสั่งต่อไปนี้

--platforms=//:windows_arm64  --extra_toolchains=@local_config_cc//:cc-toolchain-arm64_windows

คุณสามารถใช้ @local_config_cc ใน MODULE.bazel ด้วยคำสั่งต่อไปนี้

bazel_dep(name = "rules_cc", version = "0.1.1")
cc_configure = use_extension("@rules_cc//cc:extensions.bzl", "cc_configure_extension")
use_repo(cc_configure, "local_config_cc")

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

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

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

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

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

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

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

    set BAZEL_LLVM=C:\Program Files\LLVM

การเปิดใช้ Toolchain ของ Clang สำหรับการสร้าง C++ มีหลายกรณีดังนี้

  • ใน Bazel 7.0.0 ขึ้นไป ให้เพิ่มเป้าหมายแพลตฟอร์มลงใน BUILD file (เช่น ไฟล์ระดับบนสุด BUILD)

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

    จากนั้นเปิดใช้ Toolchain ของ Clang โดยระบุแฟล็กการสร้างต่อไปนี้

    --extra_toolchains=@local_config_cc//:cc-toolchain-x64_windows-clang-cl --extra_execution_platforms=//:x64_windows-clang-cl
    
  • ใน Bazel เวอร์ชันเก่ากว่า 7.0.0 แต่ใหม่กว่า 0.28 ให้เปิดใช้ Toolchain ของ Clang ด้วยแฟล็กการสร้าง --compiler=clang-cl

    หากบิลด์ของคุณตั้งค่าแฟล็ก --incompatible_enable_cc_toolchain_resolution เป็น true ให้ใช้วิธีการสำหรับ Bazel 7.0.0

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

สร้าง 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 คุณต้องมีสิ่งต่อไปนี้

  • ตัวแปลภาษา 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 โปรดดูเอกสารการออกแบบ นี้