本文档深入介绍了 Protocol Buffers 的构建系统,涵盖了 Bazel 和 CMake 构建基础设施。它描述了 Protocol Buffers 如何构建以及如何将其集成到其他项目中。
Protocol Buffers 提供了两个主要的构建系统
两个构建系统都支持所有核心 Protocol Buffers 组件,包括协议编译器(protoc)、运行时库和特定语言的代码生成器。
来源: WORKSPACE BUILD.bazel CMakeLists.txt pkg/BUILD.bazel1-100
Bazel 是 Protocol Buffers 使用的主要构建系统。它提供细粒度的依赖管理,并支持针对多种语言和平台进行构建。
Protocol Buffers 的 Bazel 工作区定义在 WORKSPACE 文件中,该文件
com_google_protobufprotobuf_deps.bzl 加载通用依赖项来源: WORKSPACE1-307
根目录的 BUILD.bazel 文件定义了主要的 Protocol Buffers 目标
| 目标 | 描述 |
|---|---|
protoc | Protocol Buffer 编译器可执行文件 |
protobuf | 主要的 C++ 运行时库 |
protobuf_lite | 适用于受限环境的轻量级 C++ 运行时库 |
protobuf_java | Java 运行时库 |
protobuf_javalite | 轻量级 Java 运行时 |
protobuf_python | Python 运行时库 |
protobuf_objc | Objective-C 运行时库 |
protobuf_rust | Rust 运行时库 |
此外,它还定义了著名类型 proto(any_proto、empty_proto 等)和实用库的目标。
来源: BUILD.bazel1-100 BUILD.bazel300-500
Bazel 提供了自定义规则,用于从 Protocol Buffer 定义生成代码
Bazel 构建规则定义在 bazel/cc_proto_library.bzl 和 bazel/upb_proto_library.bzl 等文件中。
来源: BUILD.bazel1-50 bazel/upb_proto_library.bzl1-36
pkg/BUILD.bazel 文件定义了打包 Protocol Buffers 发行版的规则
protoc_release - 打包 protoc 编译器及必需的头文件gen_src_file_lists - 生成源文件列表,供其他构建系统使用protobuf、protobuf_lite、protoc 等。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 | 构建 libprotoc | OFF |
protobuf_WITH_ZLIB | 支持 zlib 构建 | ON |
protobuf_BUILD_SHARED_LIBS | 构建共享库 | OFF |
protobuf_MSVC_STATIC_RUNTIME | 在 MSVC 上链接静态运行时 | ON |
来源: 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 配置使用来定义库目标。
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 文件定义了不同编译器和平台的配置设置
来源: 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 项目,可以将 Protocol Buffers 添加为外部依赖项
将 Protocol Buffers 添加到您的 WORKSPACE 文件中
在您的 BUILD 文件中使用 Protocol Buffers 规则
来源: WORKSPACE1-100 BUILD.bazel1-50
对于 CMake 项目,Protocol Buffers 提供了两种方法
将 Protocol Buffers 用作子项目
使用 find_package 来定位已安装的 Protocol Buffers
从 .proto 文件生成代码
来源: CMakeLists.txt1-100 CMakeLists.txt270-320
使用 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 //...
使用 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 进行开发和测试。