在 Windows 上使用 Bazel

本页面介绍了在 Windows 上使用 Bazel 的最佳实践。如需了解安装 说明,请参阅在 Windows 上安装 Bazel

已知问题

与 Windows 相关的 Bazel 问题在 GitHub 上标有“area-Windows”标签。 GitHub-Windows

最佳实践

避免路径过长问题

某些工具(包括 MSVC 编译器)在 Windows 上存在 最大路径长度限制。 为避免遇到此问题,您可以使用 --output_user_root 标志为 Bazel 指定一个较短的输出目录。

例如,将以下行添加到 bazelrc 文件中:

startup --output_user_root=C:/tmp

某些功能要求 Bazel 能够在 Windows 上创建文件符号链接, 方法是启用 开发者模式 (在 Windows 10 版本 1703 或更高版本上),或者以管理员身份运行 Bazel。 这样即可启用以下功能:

为方便起见,请将以下行添加到 bazelrc 文件中:

startup --windows_enable_symlinks

build --enable_runfiles

注意:在 Windows 上创建符号链接是一项开销很大的操作。--enable_runfiles 标志可能会创建大量文件符号链接。仅在需要时启用此功能。

运行 Bazel:MSYS2 shell、命令提示符和 PowerShell

建议: 从命令提示符 (cmd.exe) 或 PowerShell 运行 Bazel。

截至 2020 年 1 月 15 日,请勿bash(无论是 从 MSYS2 shell、Git Bash、Cygwin 还是任何其他 Bash 变体)运行 Bazel。虽然 Bazel 可能适用于大多数用例,但有些功能会中断,例如 使用 Ctrl+C 从 MSYS2 中断构建)。 此外,如果您选择在 MSYS2 下运行,则需要停用 MSYS2 的自动路径转换,否则 MSYS 会将看起来像 Unix 路径(例如 //foo:bar)的命令行实参转换为 Windows 路径。 如需了解详情,请参阅 此 StackOverflow 解答

在没有 Bash (MSYS2) 的情况下使用 Bazel

在没有 Bash 的情况下使用 bazel build

在 1.0 之前的 Bazel 版本中,构建某些规则需要使用 Bash。

从 Bazel 1.0 开始,您可以构建任何规则,而无需使用 Bash,除非该规则是:

  • genrule,因为 genrule 会执行 Bash 命令
  • sh_binarysh_test 规则,因为这些规则本身需要 Bash
  • 使用 ctx.actions.run_shell()ctx.resolve_command() 的 Starlark 规则

不过,genrule 通常用于复制文件或写入文本文件等简单任务。您可以从bazel-skylib 代码库中找到合适的规则,而无需使用 genrule(并依赖于 Bash)。在 Windows 上构建时,这些规则不需要 Bash

在没有 Bash 的情况下使用 bazel test

在 1.0 之前的 Bazel 版本中,bazel test 任何内容都需要使用 Bash。

从 Bazel 1.0 开始,您可以测试任何规则,而无需使用 Bash,但以下情况除外:

  • 您使用 --run_under
  • 测试规则本身需要 Bash(因为其可执行文件是 shell 脚本)

在没有 Bash 的情况下使用 bazel run

在 1.0 之前的 Bazel 版本中,bazel run 任何内容都需要使用 Bash。

从 Bazel 1.0 开始,您可以运行任何规则,而无需使用 Bash,但以下情况除外:

  • 您使用 --run_under--script_path
  • 测试规则本身需要 Bash(因为其可执行文件是 shell 脚本)

在没有 Bash 的情况下使用 sh_binary 和 sh_* 规则,以及 ctx.actions.run_shell()

您需要使用 Bash 来构建和测试 sh_* 规则,以及构建和测试使用 ctx.actions.run_shell()ctx.resolve_command() 的 Starlark 规则。这不仅适用于项目中的规则,还适用于项目所依赖的任何外部代码库中的规则(即使是传递依赖项)。

未来,您或许可以选择使用适用于 Linux 的 Windows 子系统 (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++ 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 的完整版本号。如果安装了多个版本,您可以通过 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++ Build Tools 安装目录

      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 架构为目标。如需为 ARM64 架构构建,请使用

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

您可以在 MODULE.bazel 中引入 @local_config_cc,方法是使用

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 启用编译器参数文件功能。

使用 Clang 构建 C++

从 0.29.0 开始,Bazel 支持使用 LLVM 的 MSVC 兼容编译器驱动程序 (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 工具链,配置取决于您的 Bazel 版本以及您使用的是 Bzlmod 还是 WORKSPACE。


Bazel 8 及更高版本

  • 使用 Bzlmod(推荐)

    1. 确保您已在 MODULE.bazel 中加载 rules_cc,并配置 CC 工具链: ```python bazel_dep(name = "rules_cc", version = "0.0.17") # Or newer

      cc_configure = use_extension("@rules_cc//cc:extensions.bzl", "cc_configure_extension") use_repo(cc_configure, "local_config_cc") ```

    2. 在 BUILD 文件(例如根 BUILD 文件)中定义 platform 目标: python platform( name = "x64_windows-clang-cl", constraint_values = [ "@platforms//cpu:x86_64", "@platforms//os:windows", "@bazel_tools//tools/cpp:clang-cl", # Alias to the @rules_cc constraint in Bazel 8+ ], )

    3. 使用以下标志启用工具链: bash --extra_toolchains=@local_config_cc//:cc-toolchain-x64_windows-clang-cl --extra_execution_platforms=//:x64_windows-clang-cl

  • 使用 WORKSPACE

    1. WORKSPACE 文件中加载 rules_cc 依赖项和工具链 : python load("@rules_cc//cc:repositories.bzl", "rules_cc_dependencies", "rules_cc_toolchains") rules_cc_dependencies() rules_cc_toolchains()

    2. 在 BUILD 文件(例如根 BUILD 文件)中定义 platform 目标: python platform( name = "x64_windows-clang-cl", constraint_values = [ "@platforms//cpu:x86_64", "@platforms//os:windows", "@bazel_tools//tools/cpp:clang-cl", # Alias to the @rules_cc constraint in Bazel 8+ ], )

    3. 使用以下标志启用工具链: bash --extra_toolchains=@local_config_cc//:cc-toolchain-x64_windows-clang-cl --extra_execution_platforms=//:x64_windows-clang-cl


Bazel 7

注意: 在 Bazel 7 中,@bazel_tools//tools/cpp:clang-cl 不是 @rules_cc 约束的别名。 如需在 Bazel 7 中正确使用 clang-clrules_cc,您必须引用 @rules_cc 代码库中的约束。标签 @rules_cc//cc/private/toolchain:clang-cl 在技术上是私有的,但对于 Bazel 7 中 WORKSPACE 和 Bzlmod 设置之间的一致行为是必需的。

  • 使用 Bzlmod

    1. 按照 Bazel 8 示例中的说明设置 MODULE.bazel

    2. 使用 @rules_cc 私有约束定义 platform 目标: python platform( name = "x64_windows-clang-cl", constraint_values = [ "@platforms//cpu:x86_64", "@platforms//os:windows", "@rules_cc//cc/private/toolchain:clang-cl", # Necessary for Bazel 7 ], )

    3. 使用以下标志启用工具链: bash --extra_toolchains=@local_config_cc//:cc-toolchain-x64_windows-clang-cl --extra_execution_platforms=//:x64_windows-clang-cl

  • 使用 WORKSPACE

    1. WORKSPACE 文件中加载 rules_cc 依赖项和工具链 : python load("@rules_cc//cc:repositories.bzl", "rules_cc_dependencies", "rules_cc_toolchains") rules_cc_dependencies() rules_cc_toolchains()

    2. 使用 @rules_cc 私有约束定义 platform 目标: python platform( name = "x64_windows-clang-cl", constraint_values = [ "@platforms//cpu:x86_64", "@platforms//os:windows", "@rules_cc//cc/private/toolchain:clang-cl", # Necessary for Bazel 7 ], )

    3. 使用以下标志启用工具链: bash --extra_toolchains=@local_config_cc//:cc-toolchain-x64_windows-clang-cl --extra_execution_platforms=//:x64_windows-clang-cl


Bazel 0.29 至 6.x

Bazel 0.28 及更早版本

  • 不支持 Clang。

构建 Java

如需构建 Java 目标,您需要:

在 Windows 上,Bazel 会为 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 会为 py_binary 规则构建两个输出文件:

  • 一个自解压缩 zip 文件
  • 一个可执行文件,用于使用自解压缩 zip 文件作为实参启动 Python 解释器

您可以运行可执行文件(其扩展名为 .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 目标,请查看此 设计 文档