简介:这份资源面向在 Windows 平台使用 C++ 进行微服务与分布式系统开发的工程师,提供基于 Visual Studio 2015 编译的 gRPC 完整开发环境,解决从源码编译到工程配置的繁琐问题。压缩包共 884 个文件,约 71.97MB,以 430 个 h 头文件、306 个 cc 源文件、64 个 proto 接口定义文件为主,并附带 18 个 lib 静态库、8 个 dll 动态库及 26 个 exe 可执行文件,同时包含 vcxproj、sln、props 等 VS 工程配置,方便直接集成。资源内置 Debug 与 Release 两套编译产物,并自带一个可运行的 helloworld 测试项目,通过 Greeter 服务的 SayHello 方法演示服务定义、Stub 生成与调用流程,便于快速验证环境。已有 1758 人学习下载,适合希望跳过编译踩坑、直接上手 gRPC 服务端与客户端开发的 C++ 开发者参考使用。
1. 从一台老开发机说起:为什么 grpc windows vs2015 这套组合至今还有人踩
上周帮一个做工业上位机的朋友收拾一台 Windows 7 开发机,机器上锁死了 Visual Studio 2015,项目里要接一个跨进程的 RPC 通信层,选来选去还是落到 gRPC C++ 上。结果从 clone 到编译通过,整整折腾了一个下午——不是 gRPC 本身难,而是 grpc windows vs2015 这套组合的坑,几乎全集中在「版本对不对得上」和「依赖从哪来」这两件事上。VS2015 的 MSVC 工具集是 v140,C++11 支持是够的,但 gRPC 从某个版本之后就开始要求 C++14 甚至 C++17,第三方依赖也跟着水涨船高,选错一个 tag,后面就是无穷无尽的编译错误。这篇笔记就是把这套环境从零装到能跑通 Hello World 的完整过程记下来,包括版本怎么挑、依赖怎么拉、CMake 参数怎么配、装崩了怎么退回去。如果你手上也是一台被 VS2015 绑住、又必须上 grpc c++ windows 的机器,照着走一遍能省掉大半天。
2. 版本选型与依赖盘点:VS2015 能吃到哪个 gRPC 版本
2.1 先确认工具集和 C++ 标准这条硬线
VS2015 对应的是 MSVC 19.00,工具集 v140。它完整支持 C++11,对 C++14 是部分支持,C++17 基本没有。gRPC C++ 的版本演进里,v1.30 之前对 C++11 还算友好,越往后越依赖 C++14/17 的语法和标准库设施。所以在这台机器上,我一般会把 gRPC 锁在 v1.28.x 到 v1.33.x 这个区间,再高就容易在编译 abseil 或者 protobuf 的时候炸出一堆constexpr和std::string_view相关的错误。这不是玄学,是工具集能力决定的。
先确认环境,打开 VS2015 的开发者命令提示符,跑一下:
cl输出里会带版本号,形如19.00.xxxxx。只要主版本是 19.00,就说明是 v140 工具集。如果机器上还装了别的 VS 版本,务必用 VS2015 自带的那个命令提示符,别用系统的 cmd,否则 cl 可能指向别的工具集,后面 CMake 生成的工程会用错编译器。
2.2 依赖清单:gRPC 不是一个人能装完的
gRPC C++ 在 Windows 上编译,绕不开这几个东西:
| 依赖 | 作用 | VS2015 下的注意点 |
|---|---|---|
| CMake | 生成 VS 工程 | 用 3.15 以上,但别用 3.20+ 里默认的新行为 |
| Git | 拉源码和子模块 | 必须带 submodule,别下 zip 包 |
| NASM | 编译 OpenSSL 汇编 | 装完要进 PATH,否则 OpenSSL 编不过 |
| Perl | OpenSSL 构建脚本 | Strawberry Perl 即可 |
| Go | 部分工具链 | 可选,但 boringssl 某些脚本会用到 |
| Ninja | 可选加速 | 用 VS 生成器时可不装 |
这里最容易翻车的是 NASM 和 Perl。很多人 clone 完直接 CMake,结果卡在 OpenSSL 或者 boringssl 的汇编阶段,报错信息还特别隐晦。我的习惯是先把 NASM、Perl、CMake、Git 全部装好并确认在 PATH 里,再动 gRPC 的源码。
2.3 拉源码:submodule 一个都不能少
gRPC 的仓库带了一堆第三方子模块,直接下 zip 是拿不到这些的。正确姿势是:
git clone --recurse-submodules -b v1.33.2 https://github.com/grpc/grpc.git cd grpc git submodule update --init --recursive--recurse-submodules保证 clone 的时候就把子模块拉下来,后面那条submodule update是双保险,防止某些子模块没跟上。版本号v1.33.2是我在 VS2015 上验证过能编过的 tag,再往前的 v1.28.x 也可以,但 v1.33.x 的 API 更稳一些。如果你拉的是 master,那基本可以放弃 VS2015 了,master 早就要求 C++17。
拉完之后检查一下third_party目录,里面应该有abseil-cpp、boringssl、protobuf、zlib等一堆目录,每个目录里都得有实际文件,空的就说明 submodule 没拉全,得重新git submodule update --init --recursive。
3. 编译安装:CMake 参数怎么配才不炸
3.1 生成 VS2015 工程:生成器名字别写错
CMake 生成工程这一步,生成器的名字必须精确。VS2015 对应的是Visual Studio 14 2015 Win64,注意是 14 不是 15,15 是 VS2017。写错了 CMake 会直接报找不到生成器。
mkdir build cd build cmake .. -G "Visual Studio 14 2015 Win64" ^ -DCMAKE_BUILD_TYPE=Release ^ -DgRPC_BUILD_TESTS=OFF ^ -DgRPC_BUILD_CSHARP_EXT=OFF ^ -DgRPC_INSTALL=ON ^ -DCMAKE_INSTALL_PREFIX=C:/grpc-install逐条说下参数。-G指定生成器,必须和本机 VS 版本严格对应。CMAKE_BUILD_TYPE在 VS 生成器下其实不直接生效,因为 VS 是多配置生成器,真正决定 Release/Debug 的是后面 build 时的--config,但写上没坏处。gRPC_BUILD_TESTS=OFF很关键,gRPC 自带的测试用例编译量巨大,而且很多测试在 VS2015 下编不过,关掉能省一半时间。gRPC_BUILD_CSHARP_EXT=OFF关掉 C# 扩展,用不上就别编。gRPC_INSTALL=ON和CMAKE_INSTALL_PREFIX是为了后面能 install 到一个固定目录,方便项目引用。
如果 CMake 报错说找不到 ZLIB 或者 OpenSSL,说明它想用系统库但没找到。gRPC 默认会自己编 boringssl 和 zlib,一般不用管,但如果你的环境里装了别的 OpenSSL 并且被 CMake 优先找到了,就可能出问题。稳妥做法是加-DgRPC_SSL_PROVIDER=package或者干脆让它用自带的 boringssl,不加额外参数就是默认自带。
3.2 编译:Release 配置 + 并行度控制
工程生成之后,用 CMake 的 build 命令直接编:
cmake --build . --config Release --target install -- /m:4--config Release指定编 Release 版,VS 生成器下必须显式指定。--target install表示编完直接安装到前面设的CMAKE_INSTALL_PREFIX。最后的/m:4是传给 MSBuild 的并行编译参数,4 是并行项目数。这个数别开太大,gRPC 编译吃内存,开 8 或者 16 很容易把机器内存打满然后卡死,我一般按物理核数的一半来设。
编译过程大概会持续 20 到 40 分钟,取决于机器性能。中途如果报错,最常见的是两类:一类是abseil里的 C++14 语法错误,说明 gRPC 版本还是选高了;另一类是boringssl的汇编错误,说明 NASM 没装好或者没进 PATH。看到这两类错误,先别急着改代码,回头检查版本和依赖。
3.3 安装产物:编完之后装到哪了
install目标跑完,C:/grpc-install下会出现几个目录:
C:/grpc-install/ bin/ # grpc_cpp_plugin.exe 等工具 include/ # grpc++、grpc、google/protobuf 头文件 lib/ # grpc++.lib、grpc.lib、libprotobuf.lib 等 cmake/ # gRPCConfig.cmake,供 find_package 用bin目录里的grpc_cpp_plugin.exe是后面生成 C++ 代码要用的插件,必须能找到。lib目录里的库文件分 Debug 和 Release,Release 版不带后缀,Debug 版带d后缀,链接的时候别搞混。cmake目录里的配置文件是给find_package(gRPC CONFIG)用的,后面在项目里引用会很方便。
4. 项目集成:从 proto 到可执行文件
4.1 写一个最小 proto 并生成代码
先建一个测试目录,写个最简单的 proto:
syntax = "proto3"; package demo; service Greeter { rpc SayHello (HelloRequest) returns (HelloReply) {} } message HelloRequest { string name = 1; } message HelloReply { string message = 1; }存成greeter.proto。然后用前面装好的工具生成 C++ 代码:
C:/grpc-install/bin/protoc.exe ^ --grpc_out=. ^ --cpp_out=. ^ --plugin=protoc-gen-grpc=C:/grpc-install/bin/grpc_cpp_plugin.exe ^ -I . ^ greeter.proto--grpc_out和--cpp_out都指定输出到当前目录。--plugin告诉 protoc 用哪个插件生成 gRPC 服务代码,路径必须指到grpc_cpp_plugin.exe。-I .是 proto 的搜索路径。跑完会生成greeter.pb.cc、greeter.pb.h、greeter.grpc.pb.cc、greeter.grpc.pb.h四个文件,前两个是消息类,后两个是服务桩类。
4.2 写服务端和客户端
服务端最小实现:
#include <grpcpp/grpcpp.h> #include "greeter.grpc.pb.h" class GreeterServiceImpl final : public demo::Greeter::Service { grpc::Status SayHello(grpc::ServerContext* context, const demo::HelloRequest* request, demo::HelloReply* reply) override { std::string prefix("Hello "); reply->set_message(prefix + request->name()); return grpc::Status::OK; } }; int main() { std::string address("0.0.0.0:50051"); GreeterServiceImpl service; grpc::ServerBuilder builder; builder.AddListeningPort(address, grpc::InsecureServerCredentials()); builder.RegisterService(&service); std::unique_ptr<grpc::Server> server(builder.BuildAndStart()); server->Wait(); return 0; }客户端最小实现:
#include <grpcpp/grpcpp.h> #include "greeter.grpc.pb.h" int main() { auto channel = grpc::CreateChannel("localhost:50051", grpc::InsecureChannelCredentials()); auto stub = demo::Greeter::NewStub(channel); demo::HelloRequest request; request.set_name("VS2015"); demo::HelloReply reply; grpc::ClientContext context; grpc::Status status = stub->SayHello(&context, request, &reply); if (status.ok()) { std::cout << reply.message() << std::endl; } return 0; }这两个文件里,grpcpp/grpcpp.h是 gRPC C++ 的总头文件,InsecureServerCredentials和InsecureChannelCredentials表示不加密,本地测试够用。ServerBuilder负责组装服务,BuildAndStart之后调Wait阻塞住。客户端用CreateChannel建通道,NewStub拿桩对象,然后像调本地函数一样调远程方法。
4.3 CMake 集成:find_package 的写法
在自己的项目里,用find_package引用前面装好的 gRPC:
cmake_minimum_required(VERSION 3.15) project(demo) set(CMAKE_CXX_STANDARD 11) set(CMAKE_CXX_STANDARD_REQUIRED ON) find_package(gRPC CONFIG REQUIRED) find_package(Protobuf CONFIG REQUIRED) add_executable(server server.cpp greeter.pb.cc greeter.grpc.pb.cc) target_link_libraries(server PRIVATE gRPC::grpc++ gRPC::grpc++_reflection) add_executable(client client.cpp greeter.pb.cc greeter.grpc.pb.cc) target_link_libraries(client PRIVATE gRPC::grpc++)CMAKE_CXX_STANDARD 11是因为 VS2015 只稳到 C++11,写 14 或 17 可能编不过。find_package(gRPC CONFIG REQUIRED)会去找前面 install 出来的gRPCConfig.cmake,所以配置的时候要加-DCMAKE_PREFIX_PATH=C:/grpc-install。gRPC::grpc++是 gRPC 导出的目标名,链接它会自动带上依赖的 protobuf 和底层库。grpc++_reflection是反射库,服务端调试用得上,不需要可以去掉。
配置和编译:
cmake .. -G "Visual Studio 14 2015 Win64" ^ -DCMAKE_PREFIX_PATH=C:/grpc-install cmake --build . --config Release跑起来先起 server,再起 client,client 那边应该打印出Hello VS2015。到这一步,整套 grpc c++ windows 环境就算通了。
5. 避坑与排查:VS2015 下最容易翻车的五个点
5.1 现象:CMake 报找不到生成器
原因:生成器名字写错,或者本机没装对应版本的 VS。VS2015 的生成器名是Visual Studio 14 2015,不是 15。如果装的是 64 位工具集,还要加Win64。
解决:先用cmake --help看本机支持的生成器列表,找到带2015的那一行,原样抄过来。如果列表里没有 2015,说明 VS2015 的 C++ 组件没装全,回安装器里补上。
5.2 现象:编译 abseil 时报一堆 C++14 语法错误
原因:gRPC 版本选高了,高版本的 abseil 用了 VS2015 不支持的 C++14 特性。
解决:退到 v1.33.x 或更低。如果已经拉了高版本,git checkout v1.33.2然后重新git submodule update --init --recursive,再清空 build 目录重新 CMake。别想着改 abseil 源码去兼容,改不完的。
5.3 现象:boringssl 编译报 NASM 相关错误
原因:NASM 没装,或者装了但没进 PATH,CMake 找不到。
解决:装 NASM 后确认nasm -v能在命令行里跑通。如果 PATH 里有了还是报错,检查是不是 32 位和 64 位版本混了,64 位工具集要用 64 位 NASM。实在不行,CMake 加-DgRPC_SSL_PROVIDER=package用系统 OpenSSL 绕过去,但系统 OpenSSL 的版本也得对得上。
5.4 现象:链接时报LNK2038或RuntimeLibrary不匹配
原因:Debug 和 Release 的库混用了,或者运行库选项(/MT 和 /MD)不一致。
解决:确认项目里链接的 gRPC 库和当前编译配置一致,Release 配 Release,Debug 配 Debug。运行库选项上,gRPC 默认用 /MD,自己的项目也保持一致,别改成 /MT。
5.5 现象:运行时报DLL load failed
原因:grpc++.dll、libprotobuf.dll这些动态库不在可执行文件的搜索路径里。
解决:把C:/grpc-install/bin加到系统 PATH,或者把需要的 DLL 拷到 exe 同目录。用dumpbin /dependents server.exe可以看 exe 依赖哪些 DLL,缺哪个补哪个。
6. 装完怎么验证:三步确认这套环境真的通了
装完不算完,得有一套能重复跑的验证流程,不然下次换台机器又得从头猜。我一般按三步走,每步都有明确的通过标准。
第一步,验证工具链本身。在命令行里跑:
C:/grpc-install/bin/protoc.exe --version C:/grpc-install/bin/grpc_cpp_plugin.exe --versionprotoc会打印 libprotoc 的版本号,grpc_cpp_plugin一般没有--version参数,直接跑会报用法错误,但只要能报出用法而不是「不是内部或外部命令」,就说明插件本身是可执行的。这一步过了,说明安装产物是完整的。
第二步,验证 proto 生成链路。拿前面那个greeter.proto,重新生成一遍代码,然后检查四个输出文件是否都非空:
dir greeter.pb.cc greeter.pb.h greeter.grpc.pb.cc greeter.grpc.pb.h四个文件大小都不为 0,且greeter.grpc.pb.h里能搜到class Greeter和SayHello,说明插件工作正常。这一步是最容易被忽略的,很多人装完 gRPC 就直接写业务代码,结果 proto 生成失败,后面全是连锁错误。
第三步,端到端跑通。先起 server,再起 client,client 输出Hello VS2015就算全通。为了确认不是偶然,我会把 server 停掉再跑一次 client,这时候 client 应该报连接失败而不是崩溃,说明错误处理路径也是通的。
| 验证项 | 通过标准 | 失败时先查 |
|---|---|---|
| protoc 版本 | 打印 libprotoc 版本号 | PATH 和安装目录 |
| 插件可执行 | 报用法而非找不到命令 | bin 目录是否在 PATH |
| proto 生成 | 四个文件非空且含服务类 | 插件路径和 proto 语法 |
| 端到端 | client 打印 Hello VS2015 | 端口占用和 DLL 依赖 |
| 断连处理 | client 报错不崩溃 | 错误处理代码 |
这套流程我每次在新机器上装完都会走一遍,前后不到五分钟,但能挡掉后面百分之八十的「明明装好了却跑不起来」。从那以后我每次配 grpc windows vs2015 环境,都强制先跑完这三步再动业务代码,省下来的排查时间远比这五分钟多。希望帮到你。
本文还有配套的精品资源,点击获取