在 Windows 上使用 Bazel

本頁說明在 Windows 上使用 Bazel 的最佳做法。如需安裝操作說明,請參閱在 Windows 上安裝 Bazel

已知問題

在 GitHub 上,與 Windows 相關的 Bazel 問題會標上「team-Windows」標籤。這裡會列出待解決的問題。

最佳做法

避免長路徑問題

部分工具在 Windows 上設有路徑長度限制,包括 MSVC 編譯器。如要避免遇到這個問題,您可以透過 --output_user_root 標記指定 Bazel 的簡短輸出目錄。

例如,在 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 的比較

建議:從命令提示字元 (cmd.exe) 或 PowerShell 執行 Bazel。

自 2020-01-15 起,請不要bash 執行 Bazel,無論是透過 MSYS2 shell、Git Bash、Cygwin 或任何其他 Bash 變化版本,都請「不要」從 bash 執行。雖然 Bazel 適用於大多數的用途,但某些事情無法正常運作,例如使用 Ctrl+C 與 MSYS2 中斷建構。此外,如果您選擇在 MSYS2 下執行,就必須停用 MSYS2 的自動路徑轉換功能,否則 MSYS 會將「看起來」為 Unix 路徑 (例如 //foo:bar) 的指令列引數轉換為 Windows 路徑。詳情請參閱這個 StackOverflow 答案

使用 Bazel,不使用 Bash (MSYS2)

使用不使用 Bash 的 Bazel 版本

Bazel 1.0 之前的版本需要 Bash 才能建立某些規則。

從 Bazel 1.0 開始,您可以建構任何不使用 Bash 的規則,但以下項目除外:

  • genrule,因為 Genrules 會執行 Bash 指令
  • sh_binarysh_test 規則,因為這類規則本質上需要使用 Bash
  • 使用 ctx.actions.run_shell()ctx.resolve_command() 的 Starlark 規則

不過,genrule 通常用於複製檔案編寫文字檔等簡單的工作。您可能會在 bazel-skylib 存放區中找到適當的規則,而不使用 genrule (視 Bash 而定)。在 Windows 上建構時,這些規則不需要 Bash

使用不搭配 Bash 的 Bazel 測試

使用 1.0 以下版本的 Bazel 版本時,必須執行 Bash 才能 bazel test 的所有作業。

從 Bazel 1.0 開始,您可以在沒有 Bash 的情況下測試任何規則,但下列情況除外:

  • 你使用「--run_under
  • 測試規則本身需要 Bash (因為這個執行檔是殼層指令碼)

使用不搭配 Bash 執行刮鬍刀

使用 1.0 以下版本的 Bazel 版本時,必須執行 Bash 才能 bazel run 的所有作業。

從 Bazel 1.0 開始,您可以在沒有 Bash 的情況下執行任何規則,但以下情況除外:

  • 你使用「--run_under」或「--script_path
  • 測試規則本身需要 Bash (因為這個執行檔是殼層指令碼)

使用去二元和 sh* 規則,以及不使用 Bash 的 ctx.actions.run_shell()

您需要 Bash 才能建構及測試 sh_* 規則,以及建構和測試使用 ctx.actions.run_shell()ctx.resolve_command() 的 Starlark 規則。這不僅適用於專案中的規則,也適用於專案所依附的任何外部存放區中的規則 (均勻)。

日後您或許可以選擇使用 Windows Subsystem for Linux (WSL) 來建構這些規則,但目前這並非 Bazel-on-Windows 子團隊的優先順序。

設定環境變數

您在 Windows 命令提示字元 (cmd.exe) 中設定的環境變數,只會在該命令提示字元工作階段中設定。如果您啟動新的 cmd.exe,就必須再次設定變數。如要在 cmd.exe 開始時設定變數,您可以在 Control Panel > System Properties > Advanced > Environment Variables... 對話方塊中將這些變數新增至使用者變數或系統變數。

在 Windows 上建構

使用 MSVC 建構 C++

如要使用 MSVC 建構 C++ 目標,您需要:

  • Visual C++ 編譯器

  • (選用) BAZEL_VCBAZEL_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++ Build Tools 的完整版本號碼。如果安裝多個版本,您可以透過 BAZEL_VC_FULL_VERSION 選擇確切的 Visual C++ Build Tools 版本,否則 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。您也可以設定 BAZEL_WINSDK_FULL_VERSION 來指定 Windows SDK 版本。您可以使用完整的 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 啟用編譯器參數檔案功能。

使用 Clang 建構 C++

自 0.29.0 版起,Bazel 支援使用 LLVM 與 MSVC 相容的編譯器驅動程式 (clang-cl.exe) 進行建構。

規定:如要使用 Clang 進行建構,您必須「同時」安裝 LLVM 和 Visual C++ Build 工具,因為雖然您是以 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:您可以透過建構旗標 --compiler=clang-cl 啟用 Clang 工具鍊。

  • 使用 --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
    
    • WORKSPACE 檔案中註冊平台和工具鍊:
    register_execution_platforms(
        ":x64_windows-clang-cl"
    )
    
    register_toolchains(
        "@local_config_cc//:cc-toolchain-x64_windows-clang-cl",
    )
    

    我們計劃在日後的 Bazel 版本中預設啟用 --incompatible_enable_cc_toolchain_resolution 標記。因此,建議您以第二種方法啟用 Clang 支援。

建構 Java

如要建構 Java 目標,您需要:

在 Windows 上,Bazel 會為 java_binary 規則建構兩個輸出檔案:

  • 一個 .jar 檔案
  • 可設定 JVM 環境並執行二進位檔的 .exe 檔案

請嘗試從其中一個專案範例建構目標:

  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 會為 py_binary 規則建構兩個輸出檔案:

  • 自我擷取 ZIP 檔案
  • 一個可執行的檔案,可將 Python 解譯器以自行擷取 ZIP 檔案做為引數來啟動

您可以執行執行檔 (其副檔名為 .exe),或是以自行擷取 ZIP 檔案做為引數來執行 Python。

請嘗試從其中一個專案範例建構目標:

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

如要進一步瞭解 Bazel 如何在 Windows 上建構 Python 目標,請參閱這份設計文件