菜单

Bazel 构建系统

相关源文件

本文档介绍了 Protocol Buffers 代码库如何使用 Bazel 作为其主要的构建系统。它涵盖了核心的 Bazel 配置、自定义构建规则和关键的构建目标。有关使用 CMake 构建 Protocol Buffers 的信息,请参阅CMake 构建系统

Protocol Buffers 中 Bazel 概述

Protocol Buffers 使用 Bazel 作为其主要的构建系统,在不同平台和语言之间提供了统一的构建体验。构建配置包括用于从 .proto 文件生成代码、编译库和运行测试的自定义规则。

来源:WORKSPACE1-308 src/google/protobuf/BUILD.bazel1-20

核心 Bazel 配置

WORKSPACE 文件

WORKSPACE 文件是 Bazel 配置的入口点。它定义了工作区的名称,并设置了 Protocol Buffers 项目所需的所有外部依赖项。

WORKSPACE 文件

  • 将工作区定义为 com_google_protobuf
  • 通过 protobuf_deps.bzl 加载通用依赖项
  • 配置特定语言的工具链(Java、Python、Ruby、Rust 等)
  • 设置 Google Test 等测试框架
  • 配置 Java 集成的 Maven 构件

来源:WORKSPACE1-30 WORKSPACE31-60 WORKSPACE61-100

自定义构建规则

Protocol Buffers 定义了几个自定义的 Bazel 规则来支持其构建过程。

这些自定义规则允许

  • 使用 cc_proto_library.proto 文件生成 C++ 代码
  • 使用 upb_proto_library 生成 μpb(micro protocol buffers)C 代码
  • 使用专用规则构建反射数据

来源:bazel/upb_proto_library.bzl1-36 src/google/protobuf/BUILD.bazel5-11

构建目标和组织

Protocol Buffers 以分层结构组织其构建目标,目标之间具有明确的依赖关系。

核心库目标

关键构建目标包括:

  • protobuf_lite:一个最小运行时库
  • protobuf:完整的运行时库,包括反射
  • protoc:Protocol Buffer 编译器
  • libupb:micro protocol buffers 运行时

来源:src/google/protobuf/BUILD.bazel355-382 src/google/protobuf/BUILD.bazel742-815

知名类型

Protocol Buffers 包含一组作为核心库一部分构建的知名类型。

这些类型定义在 .proto 文件中,并编译到 C++ 和特定语言的库中。

来源:src/google/protobuf/BUILD.bazel23-229 src/google/protobuf/BUILD.bazel242-252

测试目标

Protocol Buffers 包含用于验证功能的广泛的测试目标。

来源:src/google/protobuf/BUILD.bazel857-867 src/google/protobuf/BUILD.bazel954-1227

Protocol Buffers 的自定义规则

Protocol Buffers 中的 Bazel 规则遵循定义 proto 库,然后为不同语言生成代码的模式。

Proto 库规则模式

构建过程通常包括:

  1. 使用 .proto 文件定义 proto_library 目标
  2. 创建依赖于 proto_library 的特定语言目标
  3. 通过 protoc 和特定语言的插件生成代码

来源:src/google/protobuf/BUILD.bazel23-41 bazel/upb_proto_library.bzl8-23

Proto 库目标示例

这是“any”proto 的 proto 库定义的示例。

proto_library(
    name = "any_proto",
    srcs = ["any.proto"],
    strip_import_prefix = "/src",
)

cc_proto_library(
    name = "any_cc_proto",
    deps = [":any_proto"],
)

upb_c_proto_library(
    name = "any_upb_proto",
    deps = [":any_proto"],
)

这种模式会为所有知名类型和其他 proto 文件重复。

来源:src/google/protobuf/BUILD.bazel23-42

Map 实现和 Bazel

Protocol Buffers 中的 map 实现是一个关键组件,它展示了 Bazel 如何组织复杂的代码结构。

map 实现拥有专门的 Bazel 构建规则来处理其复杂的模板和依赖项。

来源:src/google/protobuf/map.h58-59 src/google/protobuf/map.h245-479 src/google/protobuf/map_field.h298-400

测试框架

Protocol Buffers 拥有一个由 Bazel 构建的全面的测试框架。

测试框架利用 Bazel 的能力来跨多个文件和语言组织复杂的测试依赖项。

来源:src/google/protobuf/map_test.cc1-42 src/google/protobuf/unittest.proto46-255 src/google/protobuf/map_test_util.h20-87

与 CMake 的集成

虽然 Bazel 是主要构建系统,但 Protocol Buffers 也支持使用 CMake 进行构建。

CMake 构建系统与 Bazel 并行维护,以支持 Bazel 可能不可用或不被优先选择的平台和环境。

来源:CMakeLists.txt1-25 CMakeLists.txt67-86 WORKSPACE13-16

结论

Protocol Buffers 中的 Bazel 构建系统提供了一种灵活、可扩展的方式,可以为多种语言和平台构建库。通过自定义规则和结构化依赖项,它管理着从协议定义生成代码和组织运行时库的复杂过程。

使用 Bazel 构建 Protocol Buffers 的主要优势包括:

  • 跨平台构建一致性
  • 清晰的依赖管理
  • 针对 Protocol Buffer 特定任务的自定义规则
  • 与多种语言集成
  • 全面测试

对于使用 Protocol Buffers 的开发人员来说,理解 Bazel 构建系统对于有效扩展库、添加测试或将其集成到其他项目中至关重要。

来源:WORKSPACE1-10 src/google/protobuf/BUILD.bazel1-20 bazel/upb_proto_library.bzl1-36