菜单

构建系统

相关源文件

本文档深入介绍了 Protocol Buffers 的构建系统,涵盖了 Bazel 和 CMake 构建基础设施。它描述了 Protocol Buffers 如何构建以及如何将其集成到其他项目中。

概述

Protocol Buffers 提供了两个主要的构建系统

  1. Bazel - Protocol Buffers 团队使用的主力且首选的构建系统
  2. CMake - 一个具有广泛平台支持的替代构建系统

两个构建系统都支持所有核心 Protocol Buffers 组件,包括协议编译器(protoc)、运行时库和特定语言的代码生成器。

构建系统架构

来源: WORKSPACE BUILD.bazel CMakeLists.txt pkg/BUILD.bazel1-100

Bazel 构建系统

Bazel 是 Protocol Buffers 使用的主要构建系统。它提供细粒度的依赖管理,并支持针对多种语言和平台进行构建。

工作区配置

Protocol Buffers 的 Bazel 工作区定义在 WORKSPACE 文件中,该文件

  1. 将工作区名称设置为 com_google_protobuf
  2. protobuf_deps.bzl 加载通用依赖项
  3. 配置 Java、C++、Python 和 Ruby 等语言的工具链
  4. 获取 GoogleTest、Abseil 等外部依赖项

来源: WORKSPACE1-307

主要构建目标

根目录的 BUILD.bazel 文件定义了主要的 Protocol Buffers 目标

目标描述
protocProtocol Buffer 编译器可执行文件
protobuf主要的 C++ 运行时库
protobuf_lite适用于受限环境的轻量级 C++ 运行时库
protobuf_javaJava 运行时库
protobuf_javalite轻量级 Java 运行时
protobuf_pythonPython 运行时库
protobuf_objcObjective-C 运行时库
protobuf_rustRust 运行时库

此外,它还定义了著名类型 proto(any_protoempty_proto 等)和实用库的目标。

来源: BUILD.bazel1-100 BUILD.bazel300-500

特定语言规则

Bazel 提供了自定义规则,用于从 Protocol Buffer 定义生成代码

Bazel 构建规则定义在 bazel/cc_proto_library.bzlbazel/upb_proto_library.bzl 等文件中。

来源: BUILD.bazel1-50 bazel/upb_proto_library.bzl1-36

分发与打包

pkg/BUILD.bazel 文件定义了打包 Protocol Buffers 发行版的规则

  1. protoc_release - 打包 protoc 编译器及必需的头文件
  2. gen_src_file_lists - 生成源文件列表,供其他构建系统使用
  3. 分发库 - protobufprotobuf_liteprotoc 等。

来源: pkg/BUILD.bazel1-326

CMake 构建系统

Protocol Buffers 作为 Bazel 的替代方案提供了 CMake 支持,尤其适用于与现有的基于 CMake 的项目集成。

配置和选项

CMakeLists.txt 文件定义了各种配置选项

选项描述默认
protobuf_BUILD_TESTS构建测试ON
protobuf_BUILD_CONFORMANCE构建符合性测试OFF
protobuf_BUILD_EXAMPLES构建示例OFF
protobuf_BUILD_PROTOC_BINARIES构建 protoc 编译器ON
protobuf_BUILD_LIBPROTOC构建 libprotocOFF
protobuf_WITH_ZLIB支持 zlib 构建ON
protobuf_BUILD_SHARED_LIBS构建共享库OFF
protobuf_MSVC_STATIC_RUNTIME在 MSVC 上链接静态运行时ON

来源: CMakeLists.txt1-70

构建组件

来源: CMakeLists.txt1-350 src/file_lists.cmake1-291

源文件组织

src/file_lists.cmake 文件是自动生成的,其中包含各种组件的源文件列表

  • libprotobuf_srcs - 主要 Protocol Buffers 库的源文件
  • libprotobuf_hdrs - 主要库的头文件
  • libprotobuf_lite_srcs - 轻量级库的源文件
  • libprotoc_srcs - 编译器库的源文件
  • libprotoc_hdrs - 编译器库的头文件

这些列表由 CMake 配置使用来定义库目标。

来源: src/file_lists.cmake1-291

代码生成器

Protocol Buffers 包含多种语言的代码生成器,它们作为构建过程的一部分进行构建,并包含在协议编译器中。

每个语言生成器在其自己的子目录下 src/google/protobuf/compiler/ 中定义,并有自己的 BUILD 文件。

来源: src/google/protobuf/compiler/BUILD.bazel1-200 src/google/protobuf/compiler/cpp/BUILD.bazel1-100 src/google/protobuf/compiler/java/BUILD.bazel1-100

平台特定配置

Protocol Buffers 通过平台特定配置支持各种平台和编译器。

编译器支持

build_defs/BUILD.bazel 文件定义了不同编译器和平台的配置设置

  • MSVC (Visual C++) for Windows
  • Clang-CL for Windows
  • GCC for Linux
  • Clang for macOS

来源: build_defs/BUILD.bazel1-100 build_defs/cpp_opts.bzl1-52

编译选项

build_defs/cpp_opts.bzl 文件定义了针对不同平台的 C++ 编译和链接选项

来源: build_defs/cpp_opts.bzl1-52

集成到项目中

Protocol Buffers 可以根据项目的构建系统,通过多种方式集成到其他项目中。

Bazel 集成

对于 Bazel 项目,可以将 Protocol Buffers 添加为外部依赖项

  1. 将 Protocol Buffers 添加到您的 WORKSPACE 文件中

  2. 在您的 BUILD 文件中使用 Protocol Buffers 规则

来源: WORKSPACE1-100 BUILD.bazel1-50

CMake 集成

对于 CMake 项目,Protocol Buffers 提供了两种方法

  1. 将 Protocol Buffers 用作子项目

  2. 使用 find_package 来定位已安装的 Protocol Buffers

  3. 从 .proto 文件生成代码

来源: CMakeLists.txt1-100 CMakeLists.txt270-320

构建 Protocol Buffers

使用 Bazel 构建

使用 Bazel 构建 Protocol Buffers

# Build the Protocol Buffers compiler
bazel build //:protoc

# Build the main library
bazel build //:protobuf

# Build the lightweight library
bazel build //:protobuf_lite

# Run tests
bazel test //...

来源: BUILD.bazel340-390

使用 CMake 构建

使用 CMake 构建 Protocol Buffers

mkdir build && cd build
cmake ..
cmake --build .

# Install
cmake --build . --target install

CMake 配置支持各种选项,可以通过 -D 选项传递

cmake -Dprotobuf_BUILD_TESTS=OFF -Dprotobuf_BUILD_SHARED_LIBS=ON ..

来源: CMakeLists.txt20-40 CMakeLists.txt275-350

结论

Protocol Buffers 项目使用复杂的构建系统,基于 Bazel 或 CMake,支持多种语言、平台和集成场景。构建系统会编译协议编译器、特定语言的代码生成器和运行时库,这些可以用于将 Protocol Buffers 集成到其他项目中。

双构建系统方法允许 Protocol Buffers 轻松集成到使用 Bazel 或 CMake 的项目中,而在内部,Protocol Buffers 团队主要使用 Bazel 进行开发和测试。