ARTICLE DETAIL

资讯详情

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

在 MongoDB 源码树中构建 gRPC C++:bazel、CMake 与 make 三种构建路径全解析

在 MongoDB 源码树中构建 gRPC C++:bazel、CMake 与 make 三种构建路径全解析 在 MongoDB 源码树中构建 gRPC Cbazel、CMake 与 make 三种构建路径全解析【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongogRPC C 没有单一的标准构建系统官方提供了 bazel、CMake 与 make 三条并行路径以满足不同平台与使用场景。本文以 MongoDB 仓库内 vendored 的 gRPC 官方构建文档 src/third_party/grpc/dist/BUILDING.md 为骨架完整讲解从环境准备、源码获取到三种构建方式的每一步细节并对照 MongoDB 源码树中 gRPC 的实际集成位置传输层模块、构建脚本与参数配置帮助你既能在本仓库内看懂 gRPC 是如何被引入和使用的也能独立完成 gRPC C 的源码级构建与安装。一、文档背景本仓库中的 gRPC 从何而来该构建文档位于 src/third_party/grpc/dist/BUILDING.md是 gRPC 官方仓库中面向gRPC C 贡献者与高级用户的源码构建指南仅覆盖 gRPC 自身的构建不涉及如何把 gRPC 作为依赖接入普通 C 应用后者有专门的用户指引。在 MongoDB 仓库中gRPC 不是手写的第三方代码而是通过导入脚本引入的 vendored 源码树导入脚本 src/third_party/grpc/scripts/import.sh 固定抓取mongodb-forks/grpc的v1.74.1分支并把完整源码克隆到src/third_party/grpc/dist目录dist目录因此包含BUILD、Makefile、MODULE.bazel、WORKSPACE、bazel/与src/内含abseil-cpp、boringssl、c-ares、compiler、core、cpp、proto等子目录足以支撑 gRPC 自身的构建从源码结构看该 vendored 快照是构建所需的最小集合官方完整仓库中的test/、tools/、cmake/目录并未全部随包带入因此下文提到的部分官方示例脚本如run_distrib_test_cmake_module_install.sh需在完整官方源码树中才能直接运行。在 MongoDB 侧gRPC 主要承担传输层职责实现在 src/mongo/transport/grpc/ 目录下包含client.cpp、grpc_session.cpp、channel_pool.h、async_client_factory.cpp等文件并有一份随源码附带的集成冒烟测试 grpc_source_test.cpp 可直接验证 gRPC 构建产物可用。二、构建前置条件按平台准备工具链LinuxDebian/Ubuntu 系系统使用 apt 安装基础工具链$ [sudo] apt-get install build-essential autoconf libtool pkg-config如果计划用 CMake 构建还需安装 CMake$ [sudo] apt-get install cmake如果你是 gRPC 贡献者计划构建并运行测试请额外安装$ # clang 与 LLVM C 标准库仅在 sanitizer 构建时需要 $ [sudo] apt-get install clang libc-dev其中clang与libc-dev专用于 AddressSanitizer / UBSan 等 sanitizer 构建常规构建用系统 GCC 即可。macOS先在终端中安装 Xcode 或 Xcode Command Line Tools$ [sudo] xcode-select --install随后通过 Homebrew 安装构建 gRPC 所需的工具$ brew install autoconf automake libtool shtool若计划用 CMake 构建请到 CMake 官网下载对应安装包。一个值得记录的技巧是由于 Homebrew 的 libtool 以glibtool命名运行make时显式指定环境变量可确保使用 brew 安装的版本而非系统自带版本$ LIBTOOLglibtool LIBTOOLIZEglibtoolize makeWindows使用 CMake Microsoft Visual C 编译器构建前需要准备安装 Visual Studio 2022 或更高版本将使用其中的 Visual C 编译器安装 Git安装 CMake安装 nasm 并加入PATHchoco install nasm这是 BoringSSL 的硬性要求可选安装 Ninjachoco install ninja以获得更快的构建。三、获取源码克隆仓库并初始化子模块gRPC 的许多依赖如 Abseil、BoringSSL、c-ares、protobuf以 git 子模块形式管理因此构建前必须通过--recursive或submodule update拉取子模块。Unix$ git clone -b RELEASE_TAG_HERE https://github.com/grpc/grpc $ cd grpc $ git submodule update --initWindows git clone -b RELEASE_TAG_HERE https://github.com/grpc/grpc cd grpc git submodule update --init需要特别说明的是bazel 采用与子模块不同的依赖管理模型通过WORKSPACE/MODULE.bazel与 lock 文件声明依赖因此只有使用 bazel 以外的构建工具如 CMake时才需要下载子模块。这也解释了为何本仓库的 vendored 快照保留MODULE.bazel、requirements.bazel.lock等文件——它们正是 bazel 构建所需的依赖声明。四、构建方式一bazel官方推荐bazel 是 gRPC C 的主构建系统。官方认为 bazel 能提供最好的开发者体验、更快的构建与更干净的产物构建 gRPC 至少需要 bazel1.0.0及以上版本并在 Linux、macOS、Windows 上均受支持。从 gRPC 仓库根目录执行# 构建 gRPC C $ bazel build :all运行全部 C/C 测试$ bazel test --configdbg //test/...使用 bazel 的两个关键注意事项Bazel 7 及以上版本需要关闭 bzlmod。由于 gRPC 尚未完全兼容 bzlmod需要在命令中追加--enable_bzlmodfalse。gRPC 维护者如果拥有官方测试集群可使用 gRPC 的 Remote Execution 环境显著提升构建与测试速度——该能力的配置说明位于官方源码树的tools/remote_build/README.md。在本仓库中可以看到 gRPC 的 bazel 构建规则集中在 src/third_party/grpc/dist/bazel/ 目录例如cc_grpc_library.bzl、copts.bzl、generate_cc.bzl等。此外src/third_party/grpc/dummy.cpp 的存在也印证了 bazel 的集成方式——该文件注释明确说明其唯一作用是向 bazel 暴露一个CcSharedLibraryInfo从而让 gRPC 源码树可以被上层 bazel 规则以共享库形式引用。五、构建方式二CMakeCMake 是 gRPC 另一条主推的构建路径适合需要传统 Makefile / Visual Studio 工程或系统级安装的用户。5.1 Linux / Unix使用 Make 生成器在克隆好仓库--recursive或已更新子模块后执行$ mkdir -p cmake/build $ cd cmake/build $ cmake -DCMAKE_CXX_STANDARD17 ../.. $ make如需构建共享库.so文件在配置阶段追加-DBUILD_SHARED_LIBSON。5.2 Windows使用 Visual Studio 2022 及以上版本使用 Visual Studio 生成器时CMake 会生成一个grpc.sln解决方案其中包含CMakeLists.txt定义的每个目标的 VS 工程外加 CMake 自动添加的若干便捷工程。用 Visual Studio 打开解决方案后即可浏览并构建代码 rem 在克隆好仓库--recursive 或已更新子模块后从 grpc 目录执行 md .build cd .build cmake -G Visual Studio 17 2022 -DCMAKE_CXX_STANDARD17 .. cmake --build . --config Release5.3 Windows使用 Ninja构建更快使用 Ninja 时仍需安装 Visual CVisual Studio 的一部分来编译 C/C 源码 rem 在克隆好仓库--recursive 或已更新子模块后从 grpc 目录执行 cd cmake md build cd build call %VS140COMNTOOLS%..\..\VC\vcvarsall.bat x64 cmake -GNinja -DCMAKE_BUILD_TYPERelease -DCMAKE_CXX_STANDARD17 ..\.. cmake --build .5.4 Windows DLL 构建的注意事项官方对 Windows DLL 构建的态度是尽力支持、不推荐使用不推荐的原因在于 C DLL 在 Windows 上存在固有缺陷没有稳定的 C ABI且不能安全地在一个 DLL 中分配内存、在另一个 DLL 中释放官方并不禁止构建 DLLCMake 中通过-DBUILD_SHARED_LIBSON开启但使用者需自行承担风险DLL 构建没有大规模测试覆盖为避免维护成本与测试时长增加因此可能出现回归或构建损坏。5.5 统一 C 标准版本至少 C17自 gRPC C 1.70 起gRPC 本身要求至少 C17且其依赖 Abseil 会依据编译所用的 C 版本提供不同的 API 实现例如absl::string_view在 C17 前后实现不同。因此所有 CMake 构建必须使用一致的 C 标准至少 C17否则 gRPC 与其依赖混编时可能产生 ABI/API 不一致的构建错误。这也是前文所有 CMake 命令中都显式携带-DCMAKE_CXX_STANDARD17的原因。5.6 依赖管理gRPC_ _PROVIDERgRPC 的 CMake 构建通过gRPC_depname_PROVIDER系列变量控制每个依赖的来源取值有两种module与 gRPC 一起构建依赖源码取自 gRPC 的 git 子模块package使用系统上已安装的外部依赖副本可能来自系统包管理器或通过 CMake 的CMAKE_INSTALL_PREFIX预安装。例如设置gRPC_CARES_PROVIDERmodule时CMake 会在构建 gRPC 之前先构建 c-ares而设为package时CMake 会搜索系统中已安装的 c-ares 并直接使用。gRPC 的主要依赖Abseil、c-ares、protobuf、re2、OpenSSL/BoringSSL、zlib均可通过同名变量控制。5.7 构建后安装使用 CMake 安装 gRPC 的步骤配置时设置-DgRPC_INSTALLON构建install目标。安装位置由 CMake 标准变量CMAKE_INSTALL_PREFIX控制。完整示例注意此时所有依赖都需已安装即采用package模式# NOTE: gRPC 的所有依赖需要预先安装好 $ cmake ../.. -DgRPC_INSTALLON \ -DCMAKE_BUILD_TYPERelease \ -DCMAKE_CXX_STANDARD17 \ -DgRPC_ABSL_PROVIDERpackage \ -DgRPC_CARES_PROVIDERpackage \ -DgRPC_PROTOBUF_PROVIDERpackage \ -DgRPC_RE2_PROVIDERpackage \ -DgRPC_SSL_PROVIDERpackage \ -DgRPC_ZLIB_PROVIDERpackage $ make $ make install两条版本相关的经验规则若使用 CMake 3.13 及以上版本可以以module模式构建 gRPC 的依赖并在单一步骤中把依赖与 gRPC 一并安装官方在test/distrib/cpp/run_distrib_test_cmake_module_install.sh中演示了该流程若构建的是 gRPC 1.27或使用的 CMake 3.13则依赖必须选择package模式即先安装好全部外部依赖再安装 gRPC 本身官方test/distrib/cpp/run_distrib_test_cmake.sh演示了先装依赖再装 gRPC 的流程。5.8 交叉编译交叉编译 gRPC 到其他架构时需要先为宿主架构构建protoc与grpc_cpp_plugin——因为这两个工具在 gRPC 构建过程中被直接执行必须有可在本机运行的副本。随后安装目标平台的工具链并编写一个 toolchain 文件告知 CMake 编译器与系统工具的路径通过CMAKE_TOOLCHAIN_FILE变量指定$ cmake ../.. -DCMAKE_TOOLCHAIN_FILEpath/to/file $ make官方在test/distrib/cpp/run_distrib_test_cmake_aarch64_cross.sh中提供了 aarch64 交叉编译的完整示例。5.9 SONAME 与 ABI 兼容性官方声明会在发生 ABI 破坏时尽力提升 SONAME 修订号。虽然 SONAME 变化明确标示 ABI 不兼容但官方无法对相同 SONAME 版本内部的 ABI 稳定性作出硬性保证——也就是说依赖 gRPC 二进制时仍应以版本配套为准不能仅依赖 SONAME 判断。六、构建方式三make已弃用与 protocmake曾是 gRPC 的默认构建系统但官方已不再推荐使用Makefile仅面向内部使用、不面向公众消费应改用 bazel 或 CMake。如果仍然尝试可在仓库根目录直接执行$ make若在 Linux 上遇到aclocal-1.15: command not found之类的错误通常发生在安装前置依赖之前就运行了make按以下顺序清理并重试$ git clean -f -d -x git submodule foreach --recursive git clean -f -d -x $ [sudo] apt-get install build-essential autoconf libtool pkg-config $ make关于protoc默认情况下 gRPC 依赖 Protocol Buffers需要protoc编译器来生成客户端/服务端的 stub 代码。若从源码编译 gRPC 且采用递归克隆Makefile会自动尝试编译third_party中的protoc前提是检测到你尚未安装protoc。七、回到 MongoDB仓库中的 gRPC 集成与验证理解了 gRPC 的构建方式后再看 MongoDB 仓库中 gRPC 的实际落地能更直观地理解构建 gRPC 是为了什么。7.1 传输层模块MongoDB 将 gRPC 封装为独立的传输层全部代码位于 src/mongo/transport/grpc/核心文件包括client.cpp/client.hgRPC 客户端侧的传输实现grpc_session.cpp/grpc_session_manager.cpp会话与会话管理channel_pool.h/client_cache.cpp连接复用与客户端缓存async_client_factory.cpp异步客户端工厂。7.2 运行时参数由 IDL 定义gRPC 传输层的行为可通过启动参数调节定义在 src/mongo/transport/grpc/grpc_parameters.idl配置项说明默认值 / 约束net.grpc.port别名grpcPortgRPC 监听端口默认 27021校验范围 165535net.grpc.serverMaxThreads别名grpcServerMaxThreadsgRPC 会话线程数上限默认 1000至少为 1grpcKeepAliveTimeMs已建立的 gRPC 通道发送 PING 帧检查存活的间隔毫秒默认 2147483647INT_MAX支持启动时与运行时设置运行时更新仅作用于新建通道grpcKeepAliveTimeoutMsPING 帧等待确认的超时毫秒超时则关闭连接默认 20000同样支持运行时更新仅新建通道生效这些参数从 CLI、INI 与 YAML 三种配置源解析验证逻辑由 IDL 的validator声明驱动。7.3 集成冒烟测试src/third_party/grpc/grpc_source_test.cpp 以单元测试形式验证了 gRPC 构建产物在 MongoDB 环境中的可用性测试在127.0.0.1:50051上启动一个GreeterServiceImpl服务依次调用grpc::EnableDefaultHealthCheckService(true)启用健康检查服务、grpc::reflection::InitProtoReflectionServerBuilderPlugin()注册反射插件、builder.AddListeningPort(server_address, grpc::InsecureServerCredentials())监听无认证端口、builder.RegisterService(service)注册同步服务最后builder.BuildAndStart()启动服务器若返回空指针则直接判定失败。配套的 greeter_server.h 实现了SayHello的Hello响应逻辑对应经典的 helloworld 示例。这意味着即便不把 gRPC 当作用户可见功能仅凭dist源码树与这一组测试也能在 MongoDB 的开发环境中完成构建 gRPC → 验证可用的完整闭环。八、小结gRPC C 的源码构建路径清晰且分层明确前置工具链按平台准备源码获取区分 bazel无需子模块与其他工具需要子模块构建系统上 bazel 是首选、CMake 是通用之选、make 已弃用。三个容易踩坑的细节值得牢记Bazel 7 需关闭 bzlmod、所有 CMake 构建统一使用 C17 及以上、Windows DLL 构建不受推荐。在 MongoDB 仓库中这套构建体系服务于 src/mongo/transport/grpc/ 传输层其版本、参数与集成测试均可在 src/third_party/grpc/ 目录内逐一验证。【免费下载链接】mongoThe MongoDB Database项目地址: https://gitcode.com/GitHub_Trending/mo/mongo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表