本页面介绍了如何从 Maven 迁移到 Bazel,包括 前提条件和安装步骤它介绍了 Maven 和 Bazel,并提供了使用 Guava 项目的迁移示例。
从任何构建工具迁移到 Bazel 时,最好同时拥有这两种构建工具 同时运行,直到您完全迁移开发团队、CI 和任何其他相关系统。你可以在同一个 YAML 文件中 存储库
准备工作
- 安装 Bazel(如果尚未安装)。
- 如果您是 Bazel 新手,请学习 Bazel 简介: 请先构建 Java,然后再开始迁移。本教程介绍了 Bazel 的概念、结构和标签语法。
Maven 与 Bazel 之间的区别
- Maven 使用顶级
pom.xml
文件。Bazel 支持多个构建文件 每个BUILD
文件有多个目标, 与 Maven 相比 - Maven 负责部署过程的步骤。Bazel 不会 自动部署
- Bazel 使您能够表达语言之间的依赖关系。
- 向项目添加新部分时,您可能需要使用 Bazel
BUILD
个文件。最佳实践是为每个新的 Java 添加一个BUILD
文件 软件包。
从 Maven 迁移到 Bazel
以下步骤说明了如何将项目迁移到 Bazel:
以下示例来自于对 Guava 的迁移
project 从 Maven 复制到 Bazel。通过
使用的 Guava 项目的版本为 v31.1
。使用 Guava 的示例不会遍历
但迁移过程中会显示
是手动生成或添加的
$ git clone https://github.com/google/guava.git && cd guava
$ git checkout v31.1
1. 创建 MODULE.bazel 文件
在项目的根目录下创建一个名为 MODULE.bazel
的文件。如果您的项目
没有外部依赖项,此文件可以为空。
如果您的项目依赖的文件或软件包不在上述任何一项之列,
项目的目录中,请在 MODULE.bazel 中指定这些外部依赖项
文件。您可以使用 rules_jvm_external
从 Maven 管理依赖项。对于
有关使用此规则集的说明,请参阅
README
,了解所有最新动态。
Guava 项目示例:外部依赖项
您可以列出 Guava 的外部依赖项
project
rules_jvm_external
规则集。
将以下代码段添加到 MODULE.bazel
文件中:
bazel_dep(name = "rules_jvm_external", version = "6.2")
maven = use_extension("@rules_jvm_external//:extensions.bzl", "maven")
maven.install(
artifacts = [
"com.google.code.findbugs:jsr305:3.0.2",
"com.google.errorprone:error_prone_annotations:2.11.0",
"com.google.j2objc:j2objc-annotations:1.3",
"org.codehaus.mojo:animal-sniffer-annotations:1.20",
"org.checkerframework:checker-qual:3.12.0",
],
repositories = [
"https://repo1.maven.org/maven2",
],
)
use_repo(maven, "maven")
2. 创建一个 BUILD 文件
现在,您已经定义了工作区和外部依赖项(如果
适用),您需要创建 BUILD
文件来说明您的
项目。与具有一个 pom.xml
文件的 Maven 不同,Bazel 可以使用
许多 BUILD
文件来构建项目。这些文件指定
目标,允许 Bazel 生成增量构建。
分阶段添加 BUILD
文件。首先在BUILD
您的项目,并使用 Bazel 进行初始构建。然后优化
添加更多具有更精细目标的 BUILD
文件。
在
MODULE.bazel
文件所在的目录中,创建一个文本文件并 请将其命名为BUILD
。在此
BUILD
文件中,使用适当的规则创建一个目标以进行构建 自己的项目请参考以下提示:使用适当的规则:
要使用单个 Maven 模块构建项目,请使用
java_library
规则,如下所示:java_library( name = "everything", srcs = glob(["src/main/java/**/*.java"]), resources = glob(["src/main/resources/**"]), deps = ["//:all-external-targets"], )
要构建包含多个 Maven 模块的项目,请使用
java_library
规则,如下所示:java_library( name = "everything", srcs = glob([ "Module1/src/main/java/**/*.java", "Module2/src/main/java/**/*.java", ... ]), resources = glob([ "Module1/src/main/resources/**", "Module2/src/main/resources/**", ... ]), deps = ["//:all-external-targets"], )
如需构建二进制文件,请使用
java_binary
规则:java_binary( name = "everything", srcs = glob(["src/main/java/**/*.java"]), resources = glob(["src/main/resources/**"]), deps = ["//:all-external-targets"], main_class = "com.example.Main" )
指定属性:
name
:为目标指定一个含义明确的名称。在示例中 那么目标就称为“全部”。srcs
:使用 globbing 列出项目中的所有 .java 文件。resources
:使用 globbing 列出项目中的所有资源。deps
:您需要确定 项目需求。
现在,项目的根目录下有了
BUILD
文件,接下来构建您的 确保其有效在命令行中,通过工作区 目录中,请使用bazel build //:everything
通过 Bazel 构建项目。项目现已使用 Bazel 成功构建。您需要添加 更多
BUILD
文件,以允许对项目进行增量构建。
Guava 项目示例:从一个 BUILD 文件开始
将 Guava 项目迁移到 Bazel 时,最初会使用一个 BUILD
文件
构建整个项目。这一初始 BUILD
文件的内容如下:
工作区目录:
java_library(
name = "everything",
srcs = glob([
"guava/src/**/*.java",
"futures/failureaccess/src/**/*.java",
]),
javacopts = ["-XepDisableAllChecks"],
deps = [
"@maven//:com_google_code_findbugs_jsr305",
"@maven//:com_google_errorprone_error_prone_annotations",
"@maven//:com_google_j2objc_j2objc_annotations",
"@maven//:org_checkerframework_checker_qual",
"@maven//:org_codehaus_mojo_animal_sniffer_annotations",
],
)
3. 创建更多 BUILD 文件(可选)
正如您在完成创建过程后看到的,Bazel 只需要一个 BUILD file
首次构建时您仍应考虑将 build 拆分为多个较小的区块,方法是
添加更多具有精细目标的 BUILD
文件。
包含多个目标的多个 BUILD
文件会使 build 增大
支持:
- 增加了项目的增量构建,
- 可增加构建的并行执行,
- 为未来用户提供更好的 build 可维护性,以及
- 可以控制软件包之间目标的可见性, 例如包含实现详情泄露到 公共 API。
有关添加更多 BUILD
文件的提示:
- 首先,将
BUILD
文件添加到每个 Java 软件包。从 Java 开始 依赖项最少的软件包,可以一直扩展到软件包 依赖项最多 - 在添加
BUILD
文件并指定目标时,将这些新目标添加到 依赖于它们的目标的deps
个部分。请注意,glob()
函数不会跨越软件包边界,因此,软件包的数量 增大与glob()
匹配的文件将缩小。 - 每次将
BUILD
文件添加到main
目录时,请务必添加BUILD
文件复制到相应的test
目录。 - 请注意适当限制软件包之间的可见性。
- 为了简化对
BUILD
文件设置中的错误进行问题排查,请确保 项目将在您添加每个构建文件时继续使用 Bazel 进行构建。 运行bazel build //...
以确保所有目标仍会构建。
4. 使用 Bazel 构建
您一直在使用 Bazel 进行构建,同时添加了 BUILD
文件以验证设置
。
当 BUILD
文件达到所需的粒度后,您可以使用 Bazel 执行以下操作
生成所有 build。