编译gRPC
目录
无论通过哪种语言调用gRPC,都必须要编译gRPC,因为生成proto访问类时,除了产生标准的数据定义类之外,还需要产生客户端代理类。客户端代理类必须由gRPC的各个语言的protoc插件来完成。而这些插件需要在gRPC编译后才能编译生成。
下面我们一步步的来说明如何得到gRPC。
获取gRPC源码
gRPC是开源框架,项目代码在github上,所以首先要安装github。
github安装后,在指定文件夹中,执行git命令就可以获取gRPC的所有源码。
git clone https://github.com/grpc/grpc.git
虽然在github的gRPC主页上提供了源代码打包下载,但是gRPC的依赖组件就无法自动获取了。
获取gRPC的依赖组件
正如所有的项目一样,gRPC也是需要依赖第三方库。由于在gRPC中已经通过git的.gitmodules
文件定义了依赖组件,所以只需执行git命令就可以自动获取所有的依赖组件。
git submodule init
编译gRPC
由于对其他编译工具不熟,我暂时用vs2013编译。编译过程出现的问题很多。
编译gpr,通过
编译grpc,出现错误 illegal use of this type as an expression
我查找网上的资源,原来是C语言的不允许随时定义变量,所有定义的变量都只能放在函数开头,这也是C和C++的重要区别。
将原来的
static grpc_lb_policy *create_pick_first(grpc_lb_policy_factory *factory,
grpc_lb_policy_args *args) {
if (args->num_subchannels == 0) return NULL;
pick_first_lb_policy* p = gpr_malloc(sizeof(*p));
memset(p, 0, sizeof(*p));
改为:
static pick_first_lb_policy *p;
static grpc_lb_policy *create_pick_first(grpc_lb_policy_factory *factory,
grpc_lb_policy_args *args) {
if (args->num_subchannels == 0) return NULL;
p = gpr_malloc(sizeof(*p));
memset(p, 0, sizeof(*p));
就编译通过了
编译boringssl,出现很多错误
主要是
1>D:\Projects_Framework\grpc\vsprojects\..\src\boringssl\err_data.c(17): fatal error C1083: Cannot open include file: 'openssl/base.h': No such file or directory`
我做了三种尝试
- 使用grpc的boringssl项目
问题:找不到openssl的头文件,解决:在boringssl的vs项目中添加third_party的boringssl的头文件引用
问题:D:\Projects_Framework\grpc\vsprojects\..\third_party\boringssl\crypto\asn1\t_pkey.c': No such file or directory
问题:有很多重定义。解决:在头文件引用中去掉openssl的package依赖,原因可能是openssl的package和third_party的openssl重复
但是仍然无法编译通过
- 不使用grpc的boringssl项目,而直接使用cmake生成boringssl的vsproj。
需要perl、go、yasm支持
perl安装即可
golang安装即可
yasm是一个可执行的exe,没有安装,在cmake中点击advanced,在CMAKE_ASM_NASM_COMPILER中设置路径。
但是我看在boringssl的文档里,说boringssl不能在windows的visual studio编译。只能用ninja编译。
但有考虑gRPC的vs项目中boringssl不仅仅是boringssl原始的项目文件,还有一个gRPC自己添加的文件,即使编译通过,也无法再grpc使用,所以就没具体没尝试ninja方法。
- 使用grpc的boringssl里面的py脚本
我在grpc的文件夹中发现了一个文件:src\boringssl\gen_build_yaml.py
。不知道是做什么的,安装python运行这个脚本之后,生成了很多asm文件。无法生成编译结果。
经过很多尝试也没有编译成功boringssl,在gRPC的github留言板上也有人说boringssl编译不过。如果哪位朋友成功编译,请告诉我方法,不胜感激。
编译zlib
在gRPC的vs解决方案中还有一个z项目,包含了zlib依赖库,直接通过vs也编译不过。但我发现这个z项目全是zlib的文件,没有额外的文件,所以我就在gRPC的文件夹的third_party\zlib
目录下单独编译zlib。
通过cmake生成zlib的vcproj项目,在vs中编译通过。
编译grpc_dll等其他项目均通过
至此,gRPC的核心组件除了boringssl全部编译通过。我担心在使用C++调用gRPC的时候由于缺少boringssl会造成编译不过,但是观察gRPC的C++ example,只是依赖了openssl,并没有依赖boringssl,具体的配置参考我的文章《C++调用gRPC》。
编译protobuffer
gRPC依赖protobuffer进行消息编码,因此需要依赖protobuffer。
protobuffer的编译方法在文档 third_party\protobuf\cmake\readme.md
使用cmake生成vs的解决方案protobuf.sln,编译通过。
编译protoc的gRPC插件
将protobuf的release文件夹拷贝到third_party\protobuf\cmake中
打开grpc_protoc_plugins.sln,编译所有项目,顺利通过。
生成protoc所有的gRPC插件
grpc_cpp_plugin.exe
grpc_csharp_plugin.exe
grpc_objective_c_plugin.exe
grpc_python_plugin.exe
grpc_ruby_plugin.exe
下面的文章会介绍如何使用这些插件。