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

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

startup --windows_enable_symlinks
build --enable_runfiles

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

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

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

ณ วันที่ 15-01-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 เมื่อสร้างใน 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 (เนื่องจากไฟล์ที่เรียกใช้งานได้เป็นสคริปต์เชลล์)

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

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

ในอนาคตอาจมีตัวเลือกให้ใช้ Windows Subsystem for Linux (WSL) เพื่อสร้างกฎเหล่านี้ แต่ปัจจุบันไม่ใช่สิ่งที่ทีมย่อย Bazel-on-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++ 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 หากต้องการระบุสถาปัตยกรรมเป้าหมายอื่น ให้ตั้งค่าตัวเลือกการสร้าง --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++ Build Tools เนื่องจากแม้ว่าคุณจะใช้ 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: คุณสามารถเปิดใช้เครื่องมือเชน 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 คุณต้องมีสิ่งต่อไปนี้

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