【RPC方案调研】Grpc 嵌入式移植流程

由于项目需求,准备在嵌入式上使用rpc方案,调研了多个方案,最终由于Grpc和protobuf天然的亲和性,决定对Grpc进行移植。

Grpc地址:https://github.com/grpc/grpc

Grpc的交叉编译支持三种方式:bazel,cmake,makefile;bazel 由于编译太麻烦,主要适合google内部,直接放弃了,本文主要讲解基于cmake的交叉编译方式,makefile 也是类似方式。

一  交叉编译

1. 首先下载Grpc:

    git clone [email protected]:grpc/grpc.git

2. 由于Grpc 依赖较多的第三方库,我不想在系统中都安装,所以更新submodule

    git submodule update --init 

3. 交叉编译,grpc 交叉编译比较麻烦,主要原因时grpc 中包含了很多动态生成的操作,比如:使用protoc 生成protobuf的code,使用protoc-plugin 生成rpc的code;这些操作都时在编译时执行的,而我们编译的系统时ARM上的所以运行会报错,解决这些问题的办法就是关闭无用的处理,或替换为X86的工具,具体命令如下:

 make build; // 创建编译临时目录

 cmake -DCMAKE_TOOLCHAIN_FILE=XXX.cmake -DgRPC_PROTOBUF_PROVIDER=package -DgRPC_PROTOBUF_PACKAGE_TYPE=MODULE -DProtobuf_PROTOC_EXECUTABLE=/usr/local/bin/protoc  -DgRPC_BUILD_GRPC_PYTHON_PLUGIN=OFF -DABSL_RUN_TESTS=OFF ../

实际编译时,由于有些工具会依赖protoc,会报很多编译的错误,可以使用以下命令,关闭所有plugin

cmake -DCMAKE_TOOLCHAIN_FILE=XXXX.cmake -DgRPC_PROTOBUF_PROVIDER=package -DgRPC_PROTOBUF_PACKAGE_TYPE=MODULE -DProtobuf_PROTOC_EXECUTABLE=/usr/local/bin/protoc  -DgRPC_BUILD_GRPC_PYTHON_PLUGIN=OFF -DgRPC_BUILD_GRPC_PHP_PLUGIN=OFF -DgRPC_BUILD_GRPC_OBJECTIVE_C_PLUGIN=OFF -DgRPC_BUILD_GRPC_NODE_PLUGIN=OFF -DgRPC_BUILD_GRPC_CSHARP_PLUGIN=OFF -DgRPC_BUILD_GRPC_CPP_PLUGIN=OFF -DgRPC_BUILD_CODEGEN=OFF -DgRPC_BUILD_CSHARP_EXT=OFF -DgRPC_BUILD_GRPC_RUBY_PLUGIN=OFF -DABSL_RUN_TESTS=OFF -DBUILD_TESTING=OFF -DCARES_BUILD_TOOLS=OFF -DCMAKE_INSTALL_PREFIX=XXXX ..

此外,还有几个工具编译也需要屏蔽以下,CMAKE没有选项只能屏蔽CMakeLists   

 

PS:此处将protobuf 设置为X86安装的protoc工具,其中package 表示直接从系统中查找,否则要编译grpc自带的third,需要设置为module,参照:https://stackoverflow.com/questions/52202453/cross-compiling-grpc-using-cmake

4. 执行编译操作,我们只需要使用rpc功能,所以只编译一个模块

cmake --build .  --target grpc++_unsecure 

   因为是内部通信,所以我编译的时unsecure,否则可以编译

cmake --build . --target grpc++

PS: 此处要说明一下,如果想查看有哪些可以编译的模块,可以执行 make help

 5. 目前编译 grcp++_reflection 会报错:_gRPC_CPP_PLUGIN-NOTFOUND: program not found or is not executable

由于我没用到就放弃了

二  执行测试用例

1.编译protobuf库

cmake -DCMAKE_TOOLCHAIN_FILE=XXX.cmake -Dprotobuf_BUILD_TESTS=OFF ..

2. 编写protobuf 文件

包含rpc的protobuf 文件和常规的唯一区别,就时定义一个rpc 的service,用例如下:

syntax = "proto3";

option java_multiple_files = true;
option java_package = "io.grpc.examples.helloworld";
option java_outer_classname = "HelloWorldProto";
option objc_class_prefix = "HLW";

package helloworld;

// The greeting service definition.
service Greeter {
  // Sends a greeting
  rpc SayHello (HelloRequest) returns (HelloReply) {}
}

// The request message containing the

你可能感兴趣的:(架构设计,c++,软件架构师)