ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

gRPC Bazel 构建支持详解:WORKSPACE 依赖接入、版本策略与源码实现剖析

gRPC Bazel 构建支持详解:WORKSPACE 依赖接入、版本策略与源码实现剖析 gRPC Bazel 构建支持详解WORKSPACE 依赖接入、版本策略与源码实现剖析【免费下载链接】grpcC based gRPC (C, Python, Ruby, Objective-C, PHP, C#)项目地址: https://gitcode.com/GitHub_Trending/gr/grpcgRPC 仓库的主构建系统是 BazelC、Python 与 Objective-C 三类构建规则均以 Bazel 定义为源头CMake 等其他构建系统的规则也是从 Bazel 定义生成的。本文基于 bazel_support.md 的官方说明结合 bazel/grpc_deps.bzl、bazel/grpc_extra_deps.bzl 与 MODULE.bazel 等仓库源码讲解如何在自己的 Bazel 工程WORKSPACE 或 bzlmod中引入 gRPC 依赖、当前支持的 Bazel 版本策略8.7.0以及grpc_deps/grpc_extra_deps两个仓库规则宏在底层究竟加载了哪些外部仓库。Bazel 是 gRPC 的主构建系统doc/bazel_support.md 明确给出 gRPC 对构建系统的定位grpc/grpc仓库的主要构建系统是 Bazel官方为 C、Python 和 Objective-C 提供了 Bazel 规则C 虽然同时支持 CMake 等构建系统但这些规则实际上是从 Bazel 定义生成的使用 Bazel 构建的项目引入grpc/grpc目的不仅是把 gRPC 作为库依赖还可以用 gRPC 提供的规则直接生成 protobuf 代码、stub 与 servicer 代码。这一“Bazel 为源、其余构建系统生成”的架构在仓库中有直接证据仓库根目录的 build_autogenerated.yaml、build_handwritten.yaml 与 tools/buildgen/ 目录共同承担从 Bazel 规则生成各构建系统CMake、Makefile、Ruby gemspec、CocoaPods 等所需清单的职责根 BUILD 文件中定义了核心目标grpcC 库见 BUILD与grpcC 库见 BUILD它们是下游项目最常依赖的两个标签。因此对下游 Bazel 工程而言接入 gRPC 的关键只有两步引入grpc_deps与grpc_extra_deps两个仓库规则再调用它们。在 WORKSPACE 中接入 gRPCgrpc_deps 与 grpc_extra_deps按照 doc/bazel_support.md 的“Basic Usage”一节下游项目需要在自己的WORKSPACE文件中调用grpc_deps与grpc_extra_deps仓库规则官方示例如下文档中以 v1.45.0 版本归档为示例实际使用时应按需替换为对应的发布 tag、strip_prefix与sha256workspace(name example_workspace) load(bazel_tools//tools/build_defs/repo:http.bzl, http_archive) http_archive( name com_github_grpc_grpc, strip_prefix grpc-1.45.0, sha256 ec19657a677d49af59aa806ec299c070c882986c9fcc022b1c22c2a3caf01bcd, urls [https://github.com/grpc/grpc/archive/refs/tags/v1.45.0.tar.gz], ) load(com_github_grpc_grpc//bazel:grpc_deps.bzl, grpc_deps) grpc_deps() load(com_github_grpc_grpc//bazel:grpc_extra_deps.bzl, grpc_extra_deps) grpc_extra_deps()三个步骤的含义用http_archive把 gRPC 自身作为外部仓库com_github_grpc_grpc拉入工作区仓库内repo_name即com_github_grpc_grpc见 MODULE.bazel调用grpc_deps()一次性引入编译与测试 gRPC 所需的全部第三方外部仓库调用grpc_extra_deps()引入上述外部仓库自身的传递性依赖如 protobuf、rules_go 等仓库各自声明的依赖。深入源码grpc_deps() 加载了哪些外部仓库bazel/grpc_deps.bzl 中grpc_deps()的实现是一个幂等的批量http_archive调用序列——每个仓库都先检查xxx not in native.existing_rules()若消费方工作区已声明同名仓库则跳过从而允许用户自行覆盖版本。所有urls都优先指向 gRPC 维护的镜像storage.googleapis.com/grpc-bazel-mirror/...并附原始地址作为回退这是对构建稳定性与可复现性的关键设计见 bazel/update_mirror.sh 与 bazel/update_mirror_helper.py 的镜像维护逻辑。从 bazel/grpc_deps.bzl 的源码结构看grpc_deps()主要加载以下类别的仓库类别仓库仓库名说明平台与规则集platforms、rules_cc、rules_shell、rules_java、rules_proto、bazel_skylib、bazel_featuresBazel 生态基础规则集加密与压缩boringssl、zlib打add_custom_build_file.patch补丁、openssl默认 TLS 后端为 BoringSSLzlib 提供压缩支持序列化com_google_protobuf打 protobuf.patch、grpc_protoprotoc 与 gRPC 服务 proto 定义网络与解析com_github_cares_caresc-ares使用 third_party/cares/cares.BUILD 作为 BUILD、com_googlesource_code_re2异步 DNS 解析与正则通用库com_google_abslabseil-cpp、com_google_googletest核心依赖与测试框架可观测性io_opencensus_cpp、opencensus_proto、io_opentelemetry_cppOpenCensus / OpenTelemetry 遥测xDS 生态com_envoyproxy_protoc_gen_validate、com_github_cncf_xds、dev_celcel-spec、envoy_api构建 C xDS proto 所需语言工具链io_bazel_rules_go打 rules_go.patch、bazel_gazelle、build_bazel_rules_applebuild_bazel_apple_supportObjective-C、com_google_fuzztestfuzz 测试、com_github_google_benchmark分别对应 Go 依赖、Apple 平台构建、fuzz 与基准测试其他com_google_googleapis、google_cloud_cpp、bazel_toolchains、bazel_compdbgoogleapis 导入、RBE 工具链、编译数据库在函数末尾grpc_deps()还会依次调用grpc_module_deps()补充google_cloud_cpp仓库与 bazel/grpc_python_deps.bzl 中的grpc_python_deps()后者引入 Python 规则集相关依赖对应文档中“为 Python 提供 Bazel 规则”的能力。两个容易踩坑的细节值得注意OpenSSL 仅支持 bzlmod。bazel/grpc_deps.bzl 中有一段注释“Building grpc with openssl is only supported when using bzlmod”因此 WORKSPACE 模式下openssl仓库只是被实现为只含空cc_libraryssl、crypto的 dummy 仓库保证使用 WORKSPACE 的工程能继续构建测试专用依赖grpc_test_only_deps()bazel/grpc_deps.bzl额外加载com_google_libprotobuf_mutator与yaml-cpp仅用于运行 gRPC 自身的测试源码注释标明其“仅供内部使用不建议消费方调用”。深入源码grpc_extra_deps() 初始化仓库自身的传递依赖bazel/grpc_extra_deps.bzl 中的grpc_extra_deps(ignore_version_differences False)负责调用各外部仓库自带的“依赖展开”宏使其声明的二级依赖就位。从源码调用链看它依次执行rules_shell_dependencies()/rules_shell_toolchains()Shell 规则工具链rules_java_dependencies()、protobuf_deps()、rules_proto_dependencies()、bazel_features_deps()Java / Protobuf / proto 规则链go_rules_dependencies()go_register_toolchains(version 1.22.5)gazelle_dependencies()bazel/grpc_extra_deps.bzl注册 Go 工具链供 xDS proto 的 Go 代码生成使用go_third_party()拉取 protoc-gen-validate 的 Go 第三方依赖源码注释说明其用于构建 C xDS protosapple_rules_dependencies(ignore_version_differences ...)与apple_support_dependencies()Objective-C 构建所需的 Apple 规则依赖参数ignore_version_differences直接透传给前者用于容忍 Bazel 版本差异告警switched_rules_by_language(name com_google_googleapis_imports, cc True, grpc True, python True)bazel/grpc_extra_deps.bzl只为 C、gRPC 与 Python 三种语言初始化 googleapis 目标避免无谓地展开其他语言代码生成google_cloud_cpp_deps()、py_repositories()、googletest_deps()补齐其余仓库的依赖。源码注释也直接给出了 WORKSPACE 用法模板grpc_deps()→grpc_test_only_deps()→grpc_extra_deps()的调用顺序与文档示例一致。bzlmodMODULE.bazel 下的模块依赖声明当前仓库同时提供 bzlmod 支持Bazel 8 起默认开启的模块化依赖管理MODULE.bazel 是这一路径的权威声明也是比 WORKSPACE 方式更推荐使用 gRPC 的方式module( name grpc, version 1.84.0-dev, compatibility_level 1, repo_name com_github_grpc_grpc, )MODULE.bazel 声明模块名为grpc、repo_name保持com_github_grpc_grpc与 WORKSPACE 时代的仓库名兼容。其后以bazel_dep精确声明了全部常规依赖及版本例如abseil-cpp20250512.1、boringssl0.20260616.0、c-ares1.19.1、protobuf35.1、zlib1.3.1.bcr.5、googletest1.17.0MODULE.bazelopenssl3.3.1.bcr.1MODULE.bazel——印证了“OpenSSL 构建仅在 bzlmod 下支持”的源码注释开发依赖dev_dependency True单独归类google_benchmark、yaml-cpp、fuzztest、google_cloud_cpp、libpfm等MODULE.bazelPython 侧通过rules_python注册 3.10 至 3.14 多版本工具链默认 3.11并用pip.parse(requirements_lock //:requirements.bazel.lock)锁定 pip 依赖MODULE.bazel。MODULE.bazel 中还大量使用archive_override/single_version_override覆盖 BCR 默认配置例如用f1f503da这个略新于 1.3.1 的 zlib 提交替换 BCR 版本并打补丁MODULE.bazel将 re2 声明为 BCR 版本号但实际使用 2022-04-01 快照以保持与 CMake 构建一致MODULE.bazellibpfm 因上游原始链接失效而改指 grpc-bazel-mirror 镜像MODULE.bazel。从源码结构看这些覆盖集中体现了“Bazel 侧版本必须与 CMake 等其他构建系统的锁定版本对齐”的维护策略——这正是文档中“Bazel 是源头”主张的具体落地。当前支持的 Bazel 版本8.7.0 与版本策略doc/bazel_support.md 的“Supported Versions”一节给出 gRPC 的 Bazel 版本支持策略支持Bazel 最新稳定版以及上一代大版本在转入维护模式后至少 6 个月内的版本该策略与 Google 基础 C 支持策略Foundational C Support Policy保持一致个别发布可能有更宽的兼容范围当前支持版本列表为8.7.0一项。仓库中有多处与该结论互相印证的证据bazel/supported_versions.txt 的内容仅有一行8.7.0是 CI 与工具链脚本读取的机器可读清单仓库根的 .bazelversion 文件同样写入8.7.0tools/bazel 是一个 Bazel wrapper 脚本利用 Bazel “工作区内//tools/bazel脚本可劫持 bazel 调用”的机制确保任何人在该仓库中执行bazel时都使用受支持的版本从.bazelversion读取版本号可用环境变量OVERRIDE_BAZEL_VERSION覆盖再按平台Linux x86_64 / aarch64、Darwin x86_64 / arm64、Windows MINGW/MSYS下载对应二进制见 tools/bazel下载时先尝试grpc-bazel-mirror镜像、失败再回退原始源tools/bazel设置DISABLE_BAZEL_WRAPPER可跳过 wrapper 逻辑直接使用系统 BazelOVERRIDE_BAZEL_WRAPPER_DOWNLOAD_DIR可改变二进制下载目录tools/bazel。对下游工程的含义是如果你的 Bazel 不是 8.7.0至少应先确认其落在上述策略区间内再尝试构建仓库内 .bazelrc 仅做了一件事——从旧位置导入 tools/bazel.rcimport %workspace%/tools/bazel.rc实际构建参数都集中在后者中排查 Bazel 行为差异时可以直接查看该文件。用 gRPC 的 Bazel 规则生成 protobuf / stub / servicer 代码文档指出引入 gRPC 仓库的另一个重要用途是生成 protobuf、stub 与 servicer 代码。仓库中对应规则的实现位于 bazel/cc_grpc_library.bzlcc_grpc_library规则把cc_proto与 gRPC 代码生成组合起来、bazel/generate_cc.bzl底层代码生成 action以及 bazel/grpc_build_system.bzl。在消费方 BUILD 文件中典型用法是先对服务 proto 应用cc_proto再用cc_grpc_library生成 stub/servicer 目标最后链接com_github_grpc_grpc//:grpc目标——具体写法可参考仓库内 examples/cpp/ 下各示例的 BUILD 文件与 doc/bazel_support.md 的说明。小结回到 doc/bazel_support.md 的核心结论gRPC 的 Bazel 支持分为“仓库级”与“规则级”两层——仓库级通过grpc_deps()/grpc_extra_deps()WORKSPACE或 MODULE.bazel 的模块依赖bzlmod引入 gRPC 及其完整依赖树版本策略锁定在 Bazel 8.7.0见 bazel/supported_versions.txt 与 .bazelversion规则级则提供cc_grpc_library等规则使下游项目能够直接生成 protobuf/stub/servicer 代码。由于 CMake 等其他构建系统的规则都源自 Bazel 定义理解上述 Bazel 层结构也是理解 gRPC 全部构建路径的基础。【免费下载链接】grpcC based gRPC (C, Python, Ruby, Objective-C, PHP, C#)项目地址: https://gitcode.com/GitHub_Trending/gr/grpc创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表