前言
开源项目,大部分都是通过CMake编译相关不同环境、不同平台的各个版本。
优点:可以快速生成不同平台、不同编译环境的工程文件。
缺点:生成的工程依赖本地路径和环境。
这里所搭建的环境,立志做到简洁轻巧、即拷即用的原则。
相关软件安装
这里提供一下gRPC所需要安装的软件。
git(代码仓库):https://git-scm.com/
golang(go语言):https://golang.org/dl/
cmake(安装编译工具):https://cmake.org/download/
active state perl(perl脚本解释器):https://www.activestate.com/activeperl/
nasm(汇编语言编译):https://www.nasm.us/pub/nasm/releasebuilds/
安装时候,注意path变量的勾选。
常规编译
由于国内github下载,总会出现超时错误,这里有必要科学上网。
# 配置git代理
git config --global https.proxy http://127.0.0.1:10809
git config --global https.proxy https://127.0.0.1:10809
# 获取gRPC代码
git clone -b v1.27.1 https://github.com/grpc/grpc.git
# 进入gRPC目录,下载gPRC依赖库
git submodule update --init
# 创建vsprojects目录、生成VS2017工程
md vsprojects && cd vsprojects
cmake .. -G "Visual Studio 15 2017"
# 取消git代理
git config --global--unset http.proxy
git config --global--unset https.proxy
查看下载第三方依赖库和地址。一共有15个。
[remote "origin"]
url = https://github.com/grpc/grpc.git
fetch = +refs/heads/*:refs/remotes/origin/*
[submodule "third_party/abseil-cpp"]
active = true
url = https://github.com/abseil/abseil-cpp
[submodule "third_party/benchmark"]
active = true
url = https://github.com/google/benchmark
[submodule "third_party/bloaty"]
active = true
url = https://github.com/google/bloaty.git
[submodule "third_party/boringssl"]
active = true
url = https://github.com/google/boringssl.git
[submodule "third_party/boringssl-with-bazel"]
active = true
url = https://github.com/google/boringssl.git
[submodule "third_party/cares/cares"]
active = true
url = https://github.com/c-ares/c-ares.git
[submodule "third_party/envoy-api"]
active = true
url = https://github.com/envoyproxy/data-plane-api.git
[submodule "third_party/gflags"]
active = true
url = https://github.com/gflags/gflags.git
[submodule "third_party/googleapis"]
active = true
url = https://github.com/googleapis/googleapis.git
[submodule "third_party/googletest"]
active = true
url = https://github.com/google/googletest.git
[submodule "third_party/libuv"]
active = true
url = https://github.com/libuv/libuv.git
[submodule "third_party/protobuf"]
active = true
url = https://github.com/google/protobuf.git
[submodule "third_party/protoc-gen-validate"]
active = true
url = https://github.com/envoyproxy/protoc-gen-validate.git
[submodule "third_party/udpa"]
active = true
url = https://github.com/cncf/udpa.git
[submodule "third_party/zlib"]
active = true
url = https://github.com/madler/zlib
编译了114个项目文件,我看着也迷糊。接下来我们来瘦身gRPC工程。

环境搭建
这里头一次讲解,我自己管理和搭建环境的过程,会比较细致,后续搭建就不会太详细了,这些步骤会比较费时,需要对遇见的问题逐一解决,但是可以在其中接触到环境搭建、工程配置等相关知识,如果你对这些有足够经验,会比较枯燥无味。
搭建环境一般都会使用VS2017,虽然已经有VS2019,照顾之前的很多工程都是VS2017的,而且C++17已经是最新标准,而VS2019并没有太多的改善,没有必要做到与时俱进。不过对C++20可以期待一下。
下载 gRPC代码 & 三方依赖库
gRPC下载地址:https://github.com/grpc/grpc.git 这里我下载的grpc-1.27.x.zip,再解压grpc目录下,创建vsprojects文件夹并在其文件夹中cmd。执行
cmake .. -G "Visual Studio 15 2017"

可以看出只需下载abseil-cpp、c-ares、protobuf、boringssl和zlib这五个三方依赖库即可。
Abseil:已在Google历经十多年的开发,它的目的是为Google编程人员在各种项目上的工作需求提供支持,这些项目包括Protocol Buffers、gRPC和TensorFlow等
c-ares:是用于异步DNS请求(包括名称解析)的C库,C89兼容性,MIT许可,构建并运行在POSIX,Windows,Netware,Android和更多的操作系统上。
Protobuf:是Google开源的一种可用于结构化数据串行化(序列化)的数据缓存格式,适用于数据存储以及RPC数据交换格式。Protobuf将一个文件结构化为多个message组合而成。
boringSSL:OpenSSL 是一个强大的安全套接字层密码库,囊括主要的密码算法、常用的密钥和证书封装管理功能及SSL协议,并提供丰富的应用程序供测试或其它目的使用。但是openSSL被曝出严重的安全漏洞,最有名的是Heartbleed(心脏流血)漏洞,同时openssl代码非常糟糕。Google方面对原有openSSL提交大量的漏洞并进行改造,建立分支命名为boringSSL,当然Android M系统 加上了boringSSL的一些更改。
zlib:是提供数据压缩用的函式库,由Jean-loup Gailly与Mark Adler所开发。
把下载的第三方依赖库放在gRPC目录下的third_party对应的第三方依赖库目录下。然后再次执行CMake命令,生成的grpc工程,待整理!
创建自己的工程
创建工程,工程名字为gRPCProject。创建abseil-cpp、boringssl、cares、protobuf、zlib、grpc、third_party的文件夹和readme.txt文件。

abseil-cpp、boringssl、cares、protobuf、zlib:第三方依赖库代码文件夹。
grpc:grpc的代码文件夹。
third_party:grpc所需三方依赖库代码压缩包以及所需软件安装包。
gRPCProject:grpc示例文件夹,环境搭建完成后,所写的示例代码都在这里。
readme.txt:记录所下载源码文件的版本号,和编译时遇见的问题等内容。
每个文件夹中都将有一个vsprojects文件夹,里面存放各个代码编译的VS2017的项目文件。分别将对应的代码拷贝到自己对应的目录中去。
配置编译 zlib
在zlib的vsprojects文件夹中运行
cmake..-G"Visual Studio 15 2017"
生成VS2017工程。删除无用项目项和文件。

在gRPCProject工程中加载zlib已有项目,并删掉引用中无用项和CMakeLists.txt文件。

工程配置修改,记得Debug和Release都改。 VS中的路径宏 vc++中OutDir、ProjectDir、SolutionDir各种路径 。如果不熟悉,自行补习一下~
输出配置

修改头文件路径

导入库:lib文件输出在编译输出目录中

配置编译 c-ares
c-ares的步骤跟zlib类似,重复操作即可。
配置编译 boringSSL
boringSSL中,需要保留的项目文件global_target、fipsmodule、crypto和ssl。

工程配置修改
fipsmodule、crypto和ssl 默认输出的都是静态链接库lib。可以不用改。
修改头文件路径
fipsmodule:..\crypto..\include;..\crypto\fipsmodule....\include;
crypto:..\crypto..\include;
ssl:..\ssl..\include;编译工程报错,因为global_target、fipsmodule、crypto和ssl四个项目中都用到了nasm.props。

可以统一修改,global_target.vcxproj、fipsmodule.vcxproj、crypto.vcxproj和ssl.vcxproj。将nasm.props文件拷贝到vsprojects\nasm目录下。使用文本软件打开global_target.vcxproj、fipsmodule.vcxproj、crypto.vcxproj和ssl.vcxproj,修改34行 改为 <ImportProject="$(ProjectDir)nasm\nasm.props"/>
即可。

需要注意的nasm.props文件里记录了,nasm(汇编语言编译)的安装路径 <CompilerNasm>D:/Program Files/NASM/nasm.exe</CompilerNasm>
,如果你拷贝工程到其他电脑时,就需要对应修改下CompilerNasm的路径了,否则asm文件无法编译。

配置编译 Protobuf
在protobuf的vsprojects文件夹中运行
cmake../cmake-G"Visual Studio 15 2017"-Dprotobuf_BUILD_TESTS=OFF
生成VS2017工程。这里需指定参数-Dprotobuf_BUILD_TESTS=OFF
,因为我们没有gtest。我们保留项目文件libprotobuf.vcxproj、libprotoc.vcxproj、protoc.vcxproj。
libprotobuf.vcxproj & libprotoc.lib: grpc要引入的依赖库。
protoc.exe: 通过 *.proto文件,生成各个不同语言用的命令行程序。修改头文件路径 参考上述三方依赖库
修改protoc.exe项目的链接器
protoc右键 --> 属性 --> 链接器 --> 常规 --> 附加库目录
$(SolutionDir)$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)
protoc右键 --> 属性 --> 链接器 --> 输入 --> 附加依赖项
libprotoc.lib
libprotobuf.lib
配置编译 abseil-cpp
abseil-cpp是google 开源的 C++通用库,其目标是作为标准库的补充。我印象中在grpc-1.18.0中还未引入abseil-cpp。
在abseil-cpp的vsprojects文件夹中运行
cmake..-G"Visual Studio 15 2017"
生成VS2017工程。

50多个项目看着就迷糊,引入各个库也特别凌乱。最终自行整理成了一个项目文件。这样只生成一个abseil.lib就OK了。

配置编译 grpc
现在终于到达了最后步骤,配置编译 grpc。需要关注的项目address_sorting.vcxproj、upb.vcxproj、gpr.vcxproj、grpc.vcxproj、grpc++.vcxproj。我这里需要C++和Python语言的支持,所以要关注grpc_plugin_support.vcproj、grpc_cpp_plugin.vcproj、grpc_python_plugin.vcproj项目即可。生成的grpc_cpp_plugin.exe和grpc_python_plugin.exe是生成C++和Python语言相关grpc类文件命令行工具。

将address_sorting.vcxproj、upb.vcxproj、gpr.vcxproj、grpc.vcxproj、grpc++.vcxproj这五个项目文件添加到工程中。
工程配置修改,记得Debug和Release都改。这里以较为复杂的grpc.vcxproj项目为例截图。
配置每个项目的引用,并删除CMakeLists.txt。

修改头文件路径,这里比较多

修改*.pdb文件输出路径

参考boringSSL所述,也修改*.vcxproj文件中的nasm.props路径配置,
<ImportProject="$(ProjectDir)nasm\nasm.props"/>
。
将grpc_plugin_support.vcproj、grpc_cpp_plugin.vcproj、grpc_python_plugin.vcproj 这三个项目文件添加到工程中。
工程配置修改 grpc_plugin_support.vcproj、grpc_cpp_plugin.vcproj、grpc_python_plugin.vcproj项目。
参考上面修改项目配置。
grpc_cpp_plugin.vcproj、grpc_python_plugin.vcproj附加链接器配置
grpc_cpp_plugin、grpc_python_plugin 右键 --> 属性 --> 链接器 --> 常规 --> 附加库目录
$(SolutionDir)$(Platform)\$(Configuration);%(AdditionalLibraryDirectories)
grpc_cpp_plugin、grpc_python_plugin 右键 --> 属性 --> 链接器 --> 输入 --> 附加依赖项
libprotoc.lib
libprotobuf.lib
grpc_plugin_support.lib
开始编译,但是报错了...

看着200多错误,其实改起来很简单,是运行库设置的问题; 几个工程的 运行库设置不一样了!查一下,是protobuf的项目都设置成了多线程调试 (/MTd),而其他的项目都是多线程调试 DLL (/MDd)
远程调用需要服务器、客户端两个程序实现,因此删掉gRPCProject项目,创建gRPCServerProject、gRPCClientProject项目,编写服务器、客户端测试代码。
编辑包含附加目录、附属依赖项。
设置一下项目依赖项。
将工程拷贝到任意位置,进行编译。
gRPCProject工程示例 + 写这篇文章,花费了我一天多又多的时间,算是比较费劲的一套工程示例了。
从110多个项目文件,瘦身到20个项目文件,包含了1个实用工具、2个动态库、12个静态库、3个命令行工具、2个示例程序(服务器、客户端)。动态库和静态库只是为了展示一下在工程中都有使用而已。
做到了即拷即用,可以拷贝任意有开发环境的机器中进行编译使用。只需要修改
gRPCProject\boringssl\vsprojects\nasm\nasm.props
和gRPCProject\grpc\vsprojects\nasm\nasm.props
中nasm的安装路径。
项目属性 -> 配置属性 -> C/C++ -> 代码生成 -> 运行库
都设置一样就行了 多线程调试 DLL (/MDd)。
再次编译,全全通过了~~~~~
编码测试 gRPCProject





