Windows下编译grpc+VS2019并编写简单的helloworld示例
导语: 本文记录了开源通信框架grpc在windows系统上编译的过程,以及使用VS 2019配置使用编译出来的grpc相关成果物展示demo.在window下编译grpc也是无奈啊,试过好多种办法(通过msys配置等),都不能为VS所用,所以只能开启一段旅程。 网上相关资料也有很多,这里基于grpc 和 VS 最新版本丰富下细节,做一下记录。
Step-1: 编译grpc
1-1 准备编译环境
(1) 安装Git
作用:下载grpc代码以及相关的第三方库代码。
参考:https://git-scm.com/
(2) 安装CMake
作用:用来编译
参考:https://cmake.org/download/
备注:将Cmake bin 目录配置到系统环境变量Path。
(3) 安装Perl
作用:grpc依赖的第三方库依赖的包。
参考:安装配置perl
安装过程中可能出现:internal error2503/2502错误
参考:***** 即可解决
(4) 安装Go
作用:grpc依赖的第三方库依赖的包。
参考:安装配置Go
(5) 安装yasm
作用:grpc依赖的第三方库依赖的包。
参考:安装配置yasm
备注:将vsyasm.exe所在目录配置到系统环境变量Path。
(6) 安装ninja
作用:grpc依赖的第三方库依赖的包。
参考:安装配置ninja
备注:将ninja.exe所在目录配置到系统环境变量Path。
这里面 perl go yasm ninja 可以用通过Choco(windows上的包管理工具安装),但是不推荐,除非你有梯子
如果大家不想折腾可以下载我搞好的:源码下载
1-2 下载grpc源码以及第三方依赖库源码
(1) 网速快或者有梯子的情况下,git bash下直接执行如下命令,然后耐心等待就可以了。
git clone https://github.com/grpc/grpc.git
cd grpc
git submodule update --init
git submodule update --init --recursive //确保库下载完全
cd third_party
git submodule update --init --recursive
执行过程中可能出现:error: RPC failed; curl 56 OpenSSL SSL_read: Connection was reset, errno
错误。
这是因为服务器的SSL证书没有经过第三方机构的签署,所以才报错
解决办法:
git config --global http.sslVerify "false"
(2) 网速慢的情况下,git bash下直接执行如下命令
git clone https://gitclone.com/github.com/grpc/grpc.git
git submodule update --init
执行完上述命令,可能会卡住,别慌Ctrl+C退出即可。
cd third_party/
git clone https://gitclone.com/github.com/abseil/abseil-cpp.git
git clone https://gitclone.com/github.com/google/benchmark.git
git clone https://gitclone.com/github.com/google/bloaty.git
git clone https://gitclone.com/github.com/google/boringssl.git
git clone https://gitclone.com/github.com/c-ares/c-ares.git
git clone https://gitclone.com/github.com/envoyproxy/data-plane-api.git
git clone https://gitclone.com/github.com/gflags/gflags.git
git clone https://gitclone.com/github.com/googleapis/googleapis.git
git clone https://gitclone.com/github.com/google/googletest.git
git clone https://gitclone.com/github.com/libuv/libuv.git
git clone https://gitclone.com/github.com/google/protobuf.git
git clone https://gitclone.com/github.com/envoyproxy/protoc-gen-validate.git
git clone https://gitclone.com/github.com/cncf/udpa.git
git clone https://gitclone.com/github.com/madler/zlib.git
如果个别库还是下载不下来,可以上github上用新的git url下载,或者直接下载代码包解压到相依目录。
注意下载完第三方库的源码后,有些目录需要调整到执行完git submodule update --init 一致的要求,否则Cmake的时候路径不对,例如:boringssl- -> boringssl-with-bazel /c-ares -->/cares/cares data-plane-api --> envoy-api
1-3 编译
(1) 修改编译脚本错误
由于历史原因,请更改grpc/cmake/ssl.cmake
set(_gRPC_SSL_INCLUDE_DIR ${BORINGSSL_ROOT_DIR}/src/include) --> set(_gRPC_SSL_INCLUDE_DIR ${BORINGSSL_ROOT_DIR}/include)
(2) 查询 cmake 支持的 VS 版本
cmake -G
(3) 修改 /grpc/third_party/zlib/gzguts.h
#ifdef _WIN32
# include
#pragma warning(disable:4996) // add this line
#endif
(4) 编译
lunch cmd ,cd 到代码根目录,执行如下命令。
mkdir .build
cd .build
cmake .. -G "Visual Studio 16 2019" -A x64 -DCMAKE_BUILD_TYPE=Release
如果在代码的根目录(C:\Program Files\Git\DownloadDemo\grpc.build>)执行:
cmake .. -G "Visual Studio 16 2019" -A x64 -DCMAKE_BUILD_TYPE=Release
时报错
CMake Error at CMakeLists.txt:3767 (add_library):target "grpcpp_channelz" links to target "absl::bind_front" but the target was not found
boringssl- -> boringssl-with-bazel /c-ares -->/cares/cares data-plane-api --> envoy-api
在grpc/third_party下这六个文件夹都不为空
耐心等待编译结果, 过程中会有grpc.sln 生成,生成在grpc/.build目录下
使用vs打开,右键ALL_BUILD编译:
a:如果在编译时出现:找不到"zlib.h"的错误
解决办法:找到出错的对应项目:例如grpc项目,右键grpc项目—>选择属性—>点击c/c++,选中"常规"中的"附加包含目录项",将zlib.h的路径添加进去,比如我的在:C:\Program Files\Git\grpc\third_party\zlib,
目录下。
b:编译All_build时如果出现:将警告视为错误的问题
解决办法:找到对应项目,右键—>选择属性—>C+±–>常规—>找到将警告视为错误项,置为否。(我这是crypto出现此错误)
右键INSALL编译:(其实是安装,文件会保存到C:\Program Files (x86)/grpc, 可能会没权限,使用管理员方式打开vs,之后再重复上面的动作安装即可)
grpc相关lib 主要在.build/Release/目录下
第三方lib 主要在.build/third_party/xxxx/Release/
helloworld.proto 可以从 grpc\examples\protos
下获取
greeter_server.cc和greeter_client.cc 可以从grpc\examples\cpp\helloworld
目录下获取。
grpc_cpp_plugin.exe可以从grpc\.build\Release
中获取
protoc.exe和zlib.dll可以从C:\Program Files (x86)\grpc\bin中
获取
将上述文件全部拷贝到工程目录中,然后在VS中添加helloworld.proto、greeter_server.cc和greeter_client.cc 进创建的新项目。
protoc.exe --grpc_out=. --plugin=protoc-gen-grpc=grpc_cpp_plugin.exe helloworld.proto
protoc.exe --cpp_out=. helloworld.proto
C:\Program Files\Git\grpc\include
C:\Program Files\Git\grpc\third_party\protobuf\src
将这两个目录添加进去。
或者也可以在项目目录下创建一个include文件夹,将这两个文件夹下的文件拷贝到include文件夹中,
$(ProjectDir)\include
再将上述目录添加进附加包含目录
b:配置lib包含目录
项目右键–> 属性–>链接器–>常规—>附加库目录
将
C:\Program Files\Git\grpc\.build\third_party\cares\cares\lib\Release // 中的cares.lib
C:\Program Files\Git\grpc\.build\third_party\zlib\Release // 中的 zlib.lib
C:\Program Files\Git\grpc\.build\third_party\protobuf\Release //中的libprotobuf.lib
C:\Program Files\Git\grpc\.build\Release //中的address_sorting.lib、grpc.lib、grpc++.lib、gpr.lib和grpc++_reflection.lib
添加到附加目录库。(或者在项目目录创建lib文件夹,将上述.lib文件拷贝到lib文件夹,在附加目录库中只需添加$(ProjectDir)\lib)
下列是我创建的lib文件中的文件,由于本人比较懒,直接全选拷贝过来的,存在一些无用的库,仅供参考
c:配置lib 项目名称
项目右键–> 属性–>链接器–>常规—>输入—>附加依赖项
下列是需要添加的lib库
libprotobuf.lib
grpc.lib
grpc++.lib
gpr.lib
zlib.lib
cares.lib
grpc++_reflection.lib
address_sorting.lib
Ws2_32.lib
d:预处理增加_WIN32_WINNT=0x0A00
项目右键–> 属性–>c/c++ -->预处理器—>预处理定义
5.编译2次生成server,client的exe。第一次把greeter_client.cc中的 main函数注释掉。
第二次释放第一次在greeter_client.cc中注释的main函数,将greeter_server.cc里面的main函数注释掉。一个工程只能有一个main函数。
在编译客户端时,需要在greeter_client.cc中添加下列语句
std::cin.get();//防止客户端一闪而过
6.最后生成exe文件,这里我改了名字:(运行需要将两个.exe文件和zlib.dll放在同一个目录)
7.运行server,再运行client
执行成功