本页介绍了在 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 shell 与命令提示符与 PowerShell
建议:从命令提示符 (cmd.exe
) 或 PowerShell 运行 Bazel。
自 2020 年 1 月 15 日起,请勿通过 bash
运行 Bazel,无论是通过 MSYS2 shell、Git Bash、Cygwin 还是任何其他 Bash 变体。虽然 Bazel 可能适用于大多数用例,但有些功能无法正常使用,例如使用 MSYS2 中的 Ctrl+C 中断构建。此外,如果您选择在 MSYS2 下运行,则需要停用 MSYS2 的自动路径转换,否则 MSYS 会将类似 Unix 路径(例如 //foo:bar
)的命令行参数转换为 Windows 路径。如需了解详情,请参阅 这条 StackOverflow 解答。
在不使用 Bash 的情况下使用 Bazel (MSYS2)
在不使用 Bash 的情况下使用 bazel build
1.0 之前的 Bazel 版本需要使用 Bash 构建某些规则。
从 Bazel 1.0 开始,您无需使用 Bash 即可构建任何规则,除非该规则是:
genrule
,因为 genrule 会执行 Bash 命令sh_binary
或sh_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(因为其可执行文件是 shell 脚本)
在不使用 Bash 的情况下使用 bazel run
1.0 之前的 Bazel 版本需要使用 Bash bazel run
任何内容。
从 Bazel 1.0 开始,您无需 Bash 即可运行任何规则,但在以下情况下除外:
- 您使用
--run_under
或--script_path
- 测试规则本身需要 Bash(因为其可执行文件是 shell 脚本)
使用 shbinary 和 sh* 规则,以及 ctx.actions.run_shell()(无需 Bash)
您需要使用 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++ 目标,您需要:
(可选)
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++ Build Tools 的完整版本号。如果安装了多个版本的 Visual C++ 生成工具,您可以通过BAZEL_VC_FULL_VERSION
选择确切的版本,否则 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 应用(包括 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
build 选项:
* x64(默认):--cpu=x64_windows
或无选项
* x86:--cpu=x64_x86_windows
* ARM:--cpu=x64_arm_windows
* ARM64:--cpu=arm64_windows
例如,如需为 ARM 架构构建 target,请运行以下命令:
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++ 构建工具,因为虽然您使用 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
:您可以通过 build 标志--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 工具链:
- 指定以下 build 标志:
--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", )
--incompatible_enable_cc_toolchain_resolution 标志计划在未来的 Bazel 版本中默认启用。因此,建议您使用第二种方法启用 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 目标,请参阅此设计文档。