公司动态

Windows下VS2019手动编译gRPC:从环境配置到项目集成的完整指南

📅 2026/8/25 16:38:12
Windows下VS2019手动编译gRPC:从环境配置到项目集成的完整指南
1. 项目概述为什么要在Windows上手动编译gRPC在C服务端开发领域gRPC是一个绕不开的高性能、跨语言的RPC框架。很多朋友尤其是刚从Linux/Mac环境转到Windows的开发者可能会觉得在Windows下用Visual Studio 2019VS2019编译gRPC是一件挺“劝退”的事情。网上的教程要么年代久远要么语焉不详照着做总会在某个环节卡住比如CMake配置失败、第三方库下载超时或者链接时一堆找不到符号的错误。其实手动编译gRPC的核心价值在于“掌控力”。虽然官方和vcpkg这样的包管理器提供了预编译的二进制文件但当你需要深度定制比如启用或禁用某些特定功能如OpenSSL后端、zlib压缩。调试源码在VS2019里单步跟踪gRPC的内部实现这对于理解其工作原理和排查复杂问题至关重要。版本锁定与兼容性确保项目依赖的gRPC版本与团队其他组件或生产环境完全一致避免因自动升级带来的意外。集成到特定构建系统将gRPC作为子模块submodule或CMake子项目集成到你自己的大型解决方案中。这时候从源码编译就成了必经之路。这个过程本身也是对现代C项目构建CMake、依赖管理Git Submodules和Windows开发环境配置的一次绝佳实战。接下来我会基于最新的稳定版本以1.59.0为例方法通用带你完整走一遍从环境准备到成功生成lib/dll的全过程并附上我踩过的所有坑和解决方案。2. 环境准备与核心工具链解析工欲善其事必先利其器。在Windows上编译gRPC工具链的选择和配置是成功的第一步这里面有几个关键点需要特别注意。2.1 开发环境清单与版本锁定首先确保你的系统上已经安装了以下软件并且我强烈建议使用指定的或相近的版本以避免不必要的兼容性问题Visual Studio 2019必须安装“使用C的桌面开发”工作负载。关键点需要同时勾选“MSVC v142 - VS 2019 C x64/x86 生成工具”和“Windows 10 SDK”版本10.0.19041.0或更高。我实测下来SDK版本不匹配是后续CMake生成项目失败的一个常见原因。CMake版本 3.15。推荐使用安装程序安装并勾选“将CMake添加到系统PATH”。这是整个构建过程的“总指挥”。Git用于克隆gRPC源码及其子模块。Git for Windows是标准选择。Active Perl 和 Go这是两个容易被忽略但至关重要的依赖。gRPC的构建过程需要Perl来运行一些脚本需要Go语言来编译协议缓冲区Protocol Buffers的插件。务必从官网下载并安装并将它们的bin目录如C:\Strawberry\perl\bin和C:\Go\bin添加到系统的PATH环境变量中。Ninja可选但推荐这是一个比VS自带的MSBuild更快的构建系统。你可以通过choco install ninja如果你用Chocolatey或从GitHub Release页面下载可执行文件放到PATH里。使用Ninja能显著缩短编译时间。注意环境变量PATH的修改后务必重新启动你的命令行终端如CMD或PowerShell甚至重启VS2019以确保新的路径生效。这是很多“命令找不到”错误的根源。2.2 源码获取的正确姿势Git与子模块gRPC的源码仓库使用了Git子模块来管理其核心依赖主要是google/protobufProtocol Buffers的C实现。错误的克隆方式会导致依赖缺失编译必然失败。错误做法直接在GitHub页面点击“Download ZIP”。这样下载的压缩包不包含子模块内容。正确做法使用Git命令行进行递归克隆。# 打开 PowerShell 或 Git Bash # 1. 递归克隆主仓库及子模块 git clone --recurse-submodules -b v1.59.0 https://github.com/grpc/grpc.git cd grpc # 如果已经克隆但忘了 --recurse-submodules可以进入目录后更新子模块 git submodule update --init --recursive这个过程会下载数百兆的数据因为包含了protobuf等大型子项目。请确保网络通畅如果遇到github.com连接超时可以考虑配置Git代理或使用国内镜像源。3. 构建策略选择CMake命令行 vs CMake GUI获取源码后我们面临两种主要的构建方式纯命令行和CMake GUI生成VS项目。两者各有优劣我建议你先用方式一生成VS解决方案来理解和调试熟练后再用方式二进行快速构建。3.1 方式一使用CMake生成VS2019解决方案推荐新手这种方式会生成一个标准的.sln文件你可以在VS2019的图形界面中打开像管理普通C项目一样进行编译和调试。创建构建目录在grpc源码根目录外新建一个专门用于构建的目录例如grpc_build这是一个好习惯保持源码目录的纯净。cd .. mkdir grpc_build cd grpc_build配置CMake生成器执行CMake命令指定生成器为Visual Studio 2019并指向源码目录。cmake ../grpc -G Visual Studio 16 2019 -A x64-G “Visual Studio 16 2019”指定生成器。VS2019的内部版本号是16。-A x64指定目标架构为64位。这是目前的主流选择。-DCMAKE_BUILD_TYPERelease如果你想直接生成Release配置可以在命令行添加此参数。但在VS生成器中Debug和Release配置都会生成。处理可能出现的错误找不到Windows SDK检查VS2019安装器确保安装了足够版本的Windows 10 SDK。Perl或Go未找到确认PATH环境变量已正确设置并重启了终端。下载第三方依赖如zlib, cares失败gRPC的CMake脚本会尝试在线下载一些第三方库。如果网络环境不佳这一步可能会卡住或超时。解决方案提前下载好这些依赖的源码包放在本地特定目录。在CMake命令中通过变量指定本地路径。例如对于zlib你可以添加参数-DgRPC_ZLIB_PROVIDERpackage -DZLIB_ROOTD:/path/to/your/zlib。但这需要对每个依赖库进行操作较为繁琐。更实用使用代理或配置CMake使用更快的镜像源。对于c-ares可以尝试设置环境变量CARES_SRC_URL指向一个本地或镜像文件。打开并编译解决方案CMake成功后你会在grpc_build目录下找到grpc.sln文件。用VS2019打开它。在解决方案资源管理器中你可以看到上百个项目。不需要全部编译。右键点击解决方案 - “生成解决方案”。VS会自动处理项目间的依赖关系先编译依赖项如protobuf再编译gRPC核心库和插件。这个过程耗时较长视机器性能可能需要30分钟到1小时CPU和内存占用会很高。优点直观便于在VS中调试gRPC自身的代码查看项目属性。缺点构建速度较慢且生成的中间文件庞大。3.2 方式二使用CMake与Ninja进行命令行构建推荐熟练后使用这种方式效率更高更适合集成到自动化脚本中。进入构建目录并配置cd grpc_build cmake ../grpc -G Ninja -DCMAKE_BUILD_TYPERelease -DCMAKE_INSTALL_PREFIX./install -DgRPC_INSTALLON-G Ninja指定使用Ninja构建系统。-DCMAKE_BUILD_TYPERelease明确指定构建类型Release/Debug/RelWithDebInfo。这里必须指定因为Ninja是单配置生成器。-DCMAKE_INSTALL_PREFIX./install指定安装目录。编译完成后可以使用ninja install将头文件和库文件复制到此目录便于其他项目引用。-DgRPC_INSTALLON启用安装目标。执行编译与安装ninja # 编译完成后执行安装 ninja installninja命令会启动并行编译充分利用多核CPU速度比VS的MSBuild快很多。编译完成后在./install目录下你会看到熟悉的include、lib、bin目录结构这就是你可以直接拿来用的开发包。4. 核心编译配置详解与自定义选项gRPC的CMake提供了丰富的配置选项理解它们可以帮助你定制出最适合你项目的库。4.1 关键CMake选项解析在运行cmake命令时可以通过-D参数设置这些变量-DgRPC_BUILD_TESTSOFF默认是ON。除非你需要运行gRPC的单元测试否则强烈建议设为OFF可以节省大量编译时间。-DgRPC_BUILD_CODEGENON生成protoc插件grpc_cpp_plugin等这是必须的。-DgRPC_BUILD_CSHARP_EXTOFF如果你不用C#关掉它。-DgRPC_SSL_PROVIDER选择SSL/TLS后端。可选module使用BoringSSLgRPC内置、package使用系统的OpenSSL或none。在Windows上使用module默认是最省心的CMake会自动下载并编译BoringSSL。-DgRPC_ZLIB_PROVIDER类似地选择zlib压缩支持的提供方。module默认会使用内置的zlib。-DABSL_PROPAGATE_CXX_STDON建议设置。这能更好地传递C标准版本设置避免兼容性问题。一个更完整的、针对生产环境Release版本的配置命令示例cmake ../grpc -G Ninja ^ -DCMAKE_BUILD_TYPERelease ^ -DCMAKE_INSTALL_PREFIXC:/Libraries/grpc ^ -DgRPC_INSTALLON ^ -DgRPC_BUILD_TESTSOFF ^ -DgRPC_SSL_PROVIDERmodule ^ -DgRPC_ZLIB_PROVIDERmodule ^ -DABSL_PROPAGATE_CXX_STDON4.2 静态库 vs 动态库DLL默认情况下在Windows上CMake会生成动态链接库.dll和对应的.lib导入库。如果你需要静态库-DBUILD_SHARED_LIBSOFF这个全局CMake变量会强制所有项目包括gRPC和protobuf编译为静态库.lib。注意使用静态库时你需要确保你的最终应用程序也以静态方式链接C/C运行时库/MT或/MTd否则可能会产生运行时库冲突。这需要在你的项目属性中设置。5. 实战在VS2019项目中链接并使用自定义编译的gRPC假设你已经通过ninja install将gRPC安装到了C:\Libraries\grpc目录。现在我们在一个新的VS2019控制台项目中测试它。5.1 配置VS2019项目属性创建新项目创建一个新的“控制台应用”C项目。配置包含目录项目 - 属性 - C/C - 常规 - 附加包含目录。添加C:\Libraries\grpc\include。配置库目录链接器 - 常规 - 附加库目录。添加C:\Libraries\grpc\lib。配置依赖库链接器 - 输入 - 附加依赖项。添加你需要链接的库文件名字例如grpc.lib grpc.lib gpr.lib address_sorting.lib upb.lib re2.lib absl_*.lib # 可能需要多个abseil-cpp的库如absl_strings.lib, absl_time.lib等 libprotobuf.lib libprotoc.lib技巧你可以去C:\Libraries\grpc\lib目录下查看所有生成的.lib文件将你需要的添加进来。对于Debug配置需要链接带d后缀的库如grpcd.lib。复制DLL到输出目录如果使用动态库将C:\Libraries\grpc\bin目录下的所有.dll文件如grpc.dll,grpc.dll,libprotobuf.dll等复制到你的项目可执行文件.exe的输出目录通常是$(SolutionDir)$(Configuration)\。或者在项目属性 - 生成事件 - 后期生成事件中添加命令行来自动复制例如xcopy /y “C:\Libraries\grpc\bin\*.dll” “$(OutDir)”5.2 编写一个简单的gRPC客户端测试代码你可以创建一个简单的.proto文件然后用protoc编译器生成C代码。这里假设你已经生成了helloworld.pb.h和helloworld.grpc.pb.h等文件。在你的主程序中包含必要的头文件并尝试创建一个gRPC Channel。如果项目能成功编译并链接说明你的环境配置成功了。#include grpcpp/grpcpp.h #include iostream int main() { // 尝试创建一个简单的Channel不实际连接仅测试编译链接 auto channel grpc::CreateChannel(localhost:50051, grpc::InsecureChannelCredentials()); if (channel) { std::cout “gRPC library linked successfully!” std::endl; } // 注意这里需要链接 libprotobuf.lib 等库 return 0; }6. 常见编译错误与问题排查实录即使步骤正确编译过程也可能遇到各种问题。以下是我在多次编译中遇到的典型错误及解决方法。6.1 第三方库下载失败问题CMake配置时卡在Downloading...或Building CXX object...第三方库最后报网络错误或超时。表现[CMake Error] Download failed: 6; Couldn‘t resolve host name或Timed out。解决方案手动下载根据CMake输出日志找到下载失败的URL通常是GitHub的Release包。用浏览器或下载工具手动下载到本地。查找缓存目录CMake会将这些下载缓存到C:\Users\[你的用户名]\AppData\Local\Temp下名称随机的目录或者源码目录下的cmake\build子目录中。找到对应的.tar.gz或.zip文件失败的部分。替换文件将手动下载好的文件重命名为CMake期望的名字替换掉缓存目录中下载失败的文件通常是0字节或残缺的文件。重新运行CMake重新执行CMake配置命令。CMake会检查文件完整性如果通过则会跳过下载直接解压。6.2 链接错误LNK2005、LNK1169符号重复定义问题在链接自己的项目时报大量“符号已在xxx.lib中重复定义”的错误。原因这是Windows下经典的静态库链接冲突。通常是因为gRPC的静态库和你的项目或者gRPC库和Protobuf库使用了不同的运行时库设置/MT, /MD, /MTd, /MDd。解决方案统一运行时库确保你的项目属性 - C/C - 代码生成 - 运行时库与编译gRPC时使用的设置一致。如果你用CMake默认设置编译gRPC它通常使用/MDRelease或/MDdDebug。将你的项目也设置为相同的选项。全部使用动态库如果问题复杂考虑全部使用gRPC的动态链接版本DLL这样运行时库的冲突会被隔离到各自的DLL中。6.3 编译错误C1189, C2065找不到宏或类型问题在编译你自己的项目时报错#error: “Please compile grpc with _WIN32_WINNT 0x600”或‘grpc_event’未声明的标识符。原因Windows版本宏定义不匹配或者头文件包含顺序有问题。解决方案定义_WIN32_WINNT在你的项目属性 - C/C - 预处理器 - 预处理器定义中添加_WIN32_WINNT0x0A00对应Windows 10或更高版本。检查包含路径顺序确保gRPC的头文件目录在你的项目包含路径中并且顺序在可能产生冲突的其他库如旧版本protobuf之前。清理并重建有时VS的智能感知IntelliSense会缓存错误信息。尝试“清理解决方案”然后“重新生成”。6.4 Protoc或grpc_cpp_plugin找不到问题在编译你自己的proto文件时构建系统报错找不到protoc或grpc_cpp_plugin。原因这些工具没有在系统的PATH中或者你的CMakeLists.txt没有正确找到它们。解决方案将工具目录加入PATH将C:\Libraries\grpc\bin或你的安装目录下的bin添加到系统PATH并重启VS。在CMake中指定路径在你的项目的CMakeLists.txt中使用find_program显式指定路径。find_program(PROTOC_EXECUTABLE NAMES protoc PATHS “C:/Libraries/grpc/bin” NO_DEFAULT_PATH) find_program(GRPC_CPP_PLUGIN NAMES grpc_cpp_plugin PATHS “C:/Libraries/grpc/bin” NO_DEFAULT_PATH)使用CMake的生成目标如果你将gRPC作为子目录add_subdirectory加入你的项目CMake会提供protobuf::protoc和grpc_cpp_plugin这样的导入目标在自定义命令中直接使用这些目标名即可CMake会自动处理路径。手动编译gRPC确实比直接安装二进制包要繁琐但每一步的排错过程都能加深你对这个强大框架及其生态的理解。一旦你成功搭建起这套环境后续的项目开发和深度定制就会变得游刃有余。最关键的是你获得了一个完全可控、可调试的构建基底这对于构建严肃的C后端服务至关重要。如果在实践中遇到上面没覆盖到的新问题不妨去gRPC的GitHub Issues页面搜索一下很可能已经有解决方案了。