从 Maven 迁移到 Bazel

<ph type="x-smartling-placeholder"></ph> 报告问题 <ph type="x-smartling-placeholder"></ph> 查看来源 敬上 每晚 · 7.3。 · 7.2 条 · 7.1 · 7.0 · 6.5

本页面介绍了如何从 Maven 迁移到 Bazel,包括 前提条件和安装步骤它介绍了 Maven 和 Bazel,并提供了使用 Guava 项目的迁移示例。

从任何构建工具迁移到 Bazel 时,最好同时拥有这两种构建工具 同时运行,直到您完全迁移开发团队、CI 和任何其他相关系统。你可以在同一个 YAML 文件中 存储库

准备工作

Maven 与 Bazel 之间的区别

  • Maven 使用顶级 pom.xml 文件。Bazel 支持多个构建文件 每个 BUILD 文件有多个目标, 与 Maven 相比
  • Maven 负责部署过程的步骤。Bazel 不会 自动部署
  • Bazel 使您能够表达语言之间的依赖关系。
  • 向项目添加新部分时,您可能需要使用 Bazel BUILD 个文件。最佳实践是为每个新的 Java 添加一个 BUILD 文件 软件包。

从 Maven 迁移到 Bazel

以下步骤说明了如何将项目迁移到 Bazel:

  1. 创建 MODULE.bazel 文件
  2. 创建一个 BUILD 文件
  3. 创建更多 BUILD 文件
  4. 使用 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 文件。

  1. MODULE.bazel 文件所在的目录中,创建一个文本文件并 请将其命名为 BUILD

  2. 在此 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 的示例 文件

  3. 现在,项目的根目录下有了 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。