การใช้ 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

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

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

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

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

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

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

ใช้การทดสอบ Bazel โดยไม่มี 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 (เพราะปฏิบัติการได้เป็นสคริปต์เชลล์)

ใช้กฎ shbinary และ sh* และ ctx.actions.run_shell() โดยไม่ใช้ Bash

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

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

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

ระบบจะตั้งค่าตัวแปรสภาพแวดล้อมที่ตั้งค่าไว้ใน Windows Command Prompt (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++

      set BAZEL_VC=C:\Program Files (x86)\Microsoft Visual Studio\2017\BuildTools\VC
      
    • BAZEL_VC_FULL_VERSION (ไม่บังคับ) สำหรับ Visual Studio 2017 และ 2019 คุณจะเห็นหมายเลขเวอร์ชันแบบเต็มของเครื่องมือสร้าง Visual C++ คุณจะเลือกเวอร์ชันเครื่องมือสร้าง C++ ที่แน่นอนได้ผ่านทาง 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++

      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 เพื่อใช้ SDK ของ Windows 8.1 (มี 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

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

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

Bazel สามารถตรวจหาการติดตั้ง LLVM ในระบบของคุณโดยอัตโนมัติ หรือคุณจะบอก Bazel อย่างชัดแจ้งว่า BAZEL_LLVM ติดตั้ง 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",
        ],
    )
    

    จากนั้นจึงเปิดใช้ Toolchain ของ Clang ด้วยวิธีใดวิธีหนึ่งต่อไปนี้

    • ระบุแฟล็กบิวด์ต่อไปนี้
    --extra_toolchains=@local_config_cc//:cc-toolchain-x64_windows-clang-cl --extra_execution_platforms=//:x64_windows-clang-cl
    
    • ลงทะเบียนแพลตฟอร์มและ Toolchain ในไฟล์ 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 คุณต้องมีสิ่งต่อไปนี้

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

  • ไฟล์ .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 คุณต้องมีสิ่งต่อไปนี้

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

  • ไฟล์ 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 โปรดดูเอกสาร การออกแบบนี้