当前位置: 首页 > 工具软件 > Vala_CMake > 使用案例 >

grpc在windows平台使用CMake交叉编译Android库、Linux库和Window库

须曜文
2023-12-01

grpc编译问题

编译方法

一、Windows库编译方法

  1. 安装cmake和git
  2. 从github上下载gRPC源码, 地址:https://github.com/grpc/grpc.git
    git clone --recurse-submodules -b v1.45.0 --depth 1 --shallow-submodules https://github.com/grpc/grpc
    如果出现下载第三方库失败,可使用下面命令直到完整下载好;或者使用ssh方式进行下载(较快)
    cd grpc
    git submodule update --init
  3. 进入命令行终端界面,进入grpc/cmake目录下:
    1)在cmake目录下新建build文件夹,并切换到该目录
    mkdir -p build
    cd build
  1. 使用cmake工具生成vs工程配置文件
    cmake -A “Win32” -DgRPC_INSTALL=ON -DgRPC_BUILD_TESTS=OFF -DCMAKE_INSTALL_PREFIX=D:\gRPC …/…
    如果有出现编译错误(忘记编译信息是什么了,是在"∞"附近),即把编译信息提示错误的文件改成UTF-8 BOM再重新编译,就可以通过编译。
    3)安装grpc,生成相应的include、lib等文件夹
    make install
    如果上述指令无效,请使用下面替代指令
    cmake -DBUILD_TYPE=Debug -P cmake_install.cmake

二. Android库编译方法:

gcc编译

1、进入命令行终端界面,进入grpc/cmake/build目录下,使用cmake工具生成Android平台库配置文件
①使用“Ninja”进行构建速度较快,用多线程进行编译,若有编译错误,会有很多错误信息,不好定位错误信息。
cmake -G “Ninja” -DANDROID_ABI=armeabi-v7a -DANDROID_NDK=E:\Company\Company_Environment\android-ndk -DCMAKE_BUILD_TYPE=Release -DCMAKE_MAKE_PROGRAM=D:\tools\Ninja\ninja -DCMAKE_TOOLCHAIN_FILE=E:\Company\Company_Environment\android-ndk\build\cmake\android.toolchain.cmake -DANDROID_PLATFORM=android-22 -DANDROID_STL=gnustl_static -DANDROID_TOOLCHAIN=gcc -DCMAKE_INSTALL_PREFIX=E:\grpc-gen\gnustd_static\v1.46\Android\Release -D_gRPC_CPP_PLUGIN=D:\tools\grpc\v1.46\grpc_cpp_plugin.exe -D_gRPC_PROTOBUF_PROTOC_EXECUTABLE=D:\tools\grpc\v1.46\protoc.exe …/…
②使用“Unix Makefiles”进行构建速度慢,但是能够很好的定位错误点。
cmake -G “Unix Makefiles” -DANDROID_ABI=armeabi-v7a -DANDROID_NDK=E:\Company\Company_Environment\android-ndk -DCMAKE_BUILD_TYPE=Release -DCMAKE_MAKE_PROGRAM=E:\Company\Company_Environment\android-ndk\prebuilt\windows-x86_64\bin\make.exe -DCMAKE_TOOLCHAIN_FILE=E:\Company\Company_Environment\android-ndk\build\cmake\android.toolchain.cmake -DANDROID_PLATFORM=android-22 -DANDROID_STL=gnustl_static -DANDROID_TOOLCHAIN=gcc -DCMAKE_INSTALL_PREFIX=E:\grpc-gen\gnustd_static\v1.46\Android\Release -D_gRPC_CPP_PLUGIN=D:\tools\grpc\v1.46\grpc_cpp_plugin.exe -D_gRPC_PROTOBUF_PROTOC_EXECUTABLE=D:\tools\grpc\v1.46\protoc.exe …/…
2、安装grpc,生成相应的include、lib等文件夹
make install

clang编译

和上面方式一致,不同的只是指令中的参数。
“Ninja”:
cmake -G “Ninja” -DANDROID_ABI=armeabi-v7a -DANDROID_NDK=E:\Company\Company_Environment\android-ndk -DCMAKE_BUILD_TYPE=Release -DCMAKE_MAKE_PROGRAM=D:\tools\Ninja\ninja -DCMAKE_TOOLCHAIN_FILE=E:\Company\Company_Environment\android-ndk\build\cmake\android.toolchain.cmake -DANDROID_PLATFORM=android-22 -DANDROID_STL=gnustl_static -DANDROID_TOOLCHAIN=clang -DCMAKE_INSTALL_PREFIX=E:\grpc-gen\gnustd_static\v1.46\Android\Release -D_gRPC_CPP_PLUGIN=D:\tools\grpc\v1.46\grpc_cpp_plugin.exe -D_gRPC_PROTOBUF_PROTOC_EXECUTABLE=D:\tools\grpc\v1.46\protoc.exe …/…
“Unix Makefiles”:
cmake -G “Unix Makefiles” -DANDROID_ABI=armeabi-v7a -DANDROID_NDK=E:\Company\Company_Environment\android-ndk -DCMAKE_BUILD_TYPE=Release -DCMAKE_MAKE_PROGRAM=E:\Company\Company_Environment\android-ndk\prebuilt\windows-x86_64\bin\make.exe -DCMAKE_TOOLCHAIN_FILE=E:\Company\Company_Environment\android-ndk\build\cmake\android.toolchain.cmake -DANDROID_PLATFORM=android-22 -DANDROID_STL=gnustl_static -DANDROID_TOOLCHAIN=clang -DCMAKE_INSTALL_PREFIX=E:\grpc-gen\gnustd_static\v1.46\Android\Release -D_gRPC_CPP_PLUGIN=D:\tools\grpc\v1.46\grpc_cpp_plugin.exe -D_gRPC_PROTOBUF_PROTOC_EXECUTABLE=D:\tools\grpc\v1.46\protoc.exe …/…
注意:_gRPC_CPP_PLUGIN和_gRPC_PROTOBUF_PROTOC_EXECUTABLE中的参数是通过Window平台编译出来的可执行文件。

你在编译过程可能会遇到下面编译错误,逐一解决即可。
①问题1:链接错误
通过修改链接的顺序,可使得报错数量减少,说明库之间具有依赖性。
具体解决方法:添加链接参数-Wl,–start-group <…> -Wl,–end-group, 连接器会循环链接静态库,无需在意静态库内部依赖问题。
eg. target_link_libraries(native-lib -Wl,–start-group grpcpp_channelz grpc++unsecure grpc++reflection … --end-group)
②问题2:编译错误
Compile Android Error fatal error opening dependency file No such file or directory。
报错原因:The reason why you got this error is because your cocos creator project folder is too deep and/or your parent folder and your project folder name is too long.
解决方法:Try moving it up.Because the whole path is too long so it can’t compile those error files into the target path。
ege.将E:\open source code\grpc_v1.46… 工作目录移动到E:\grpc_v1.46…
③问题3:编译错误
error: undefined reference to ‘stderr’
报错原因:代码中使用了大量的标准IO设备:stderr 等,这些在NDK15以后,这些都不被支持了,代码本身没问题,只是编译器链接时找不到对应的静态库定义了。
解决方法:在编译选项中添加语句-D__ANDROID_API
=[你的android API版本号]即可.
ege. 编译grpc静态库 添加参数 -DANDROID_PLATFORM=android-22(指定Android 5.1(API级别22))
④问题4:编译错误
error: undefined reference to ‘std::log2’、‘std::round’等数学函数
报错原因:Android平台的C++标准库的数学函数使用的是C98下<math.h>的函数进行实现,实质C++11的数学库也是采用了C98下数学库,只是做了简单的封装。
解决方法:若要修改需要重新编译Android下C++库静态库,此方法不知道如何重新编译故没有采用,采用笨方法将使用数学库的地方将std作用域去掉。
⑤问题5:编译错误
error: undefined reference to std::to_string’
报错原因:Android平台的C++标准库未实现std::to_string
解决方法: 将std::to_string 方法重写.

#include <sstream>
template <typename T>
std::string to_string(T val)
{
    std::stringstream stream;
    stream << val;
    return stream.str();
}

⑥问题6:编译错误
error: 错误信息较长,当时未记录。百度后可找到相应原因和方法。
报错原因:编译参数-Os过于优化代码,将库里面的代码进行篡改。
解决方法: 打开Android-ndk/build/cmake/android.toolchain.cmake文件,修改编译优化从-Os 改成 -O2.

三. Linux库编译方法:

gcc编译

cmake -G “Unix Makefiles” -DCMAKE_BUILD_TYPE=Release -DCMAKE_TOOLCHAIN_FILE=D:\tools\grpc\cross-compile\linux\linux.toolchain.cmake -DCMAKE_MAKE_PROGRAM=E:\Company\Company_Environment\makecore\make.exe -DCMAKE_INSTALL_PREFIX=…/…/ …/…
注意:_gRPC_CPP_PLUGIN和_gRPC_PROTOBUF_PROTOC_EXECUTABLE中的参数是通过Window平台编译出来的可执行文件。linux.toolchain.cmake文件内容如下

set(CMAKE_SYSTEM_NAME Linux)
set(CMAKE_SYSTEM_PROCESSOR armv7l)

set(CMAKE_C_COMPILER E:/Company/Company_Environment/makecore/gcc-armhf/bin/arm-linux-gnueabihf-gcc.exe)
set(CMAKE_CXX_COMPILER E:/Company/Company_Environment/makecore/gcc-armhf/bin/arm-linux-gnueabihf-g++.exe)
set(CMAKE_ADDR2LINE E:/Company/Company_Environment/makecore/gcc-armhf/bin/arm-linux-gnueabihf-addr2line.exe)
set(CMAKE_AR E:/Company/Company_Environment/makecore/gcc-armhf/bin/arm-linux-gnueabihf-ar.exe)
set(CMAKE_RANLIB E:/Company/Company_Environment/makecore/gcc-armhf/bin/arm-linux-gnueabihf-ranlib.exe)
set(CMAKE_CXX_COMPILER_AR E:/Company/Company_Environment/makecore/gcc-armhf/bin/arm-linux-gnueabihf-gcc-ar.exe)
set(CMAKE_CXX_COMPILER_RANLIB E:/Company/Company_Environment/makecore/gcc-armhf/bin/arm-linux-gnueabihf-gcc-ranlib.exe)
set(CMAKE_C_COMPILER_AR E:/Company/Company_Environment/makecore/gcc-armhf/bin/arm-linux-gnueabihf-gcc-ar.exe)
set(CMAKE_C_COMPILER_RANLIB E:/Company/Company_Environment/makecore/gcc-armhf/bin/arm-linux-gnueabihf-gcc-ranlib.exe)
set(CMAKE_Fortran_COMPILER E:/Company/Company_Environment/makecore/gcc-armhf/bin/arm-linux-gnueabihf-gfortran.exe)
set(CMAKE_OBJCOPY E:/Company/Company_Environment/makecore/gcc-armhf/bin/arm-linux-gnueabihf-objcopy.exe)
set(CMAKE_OBJDUMP E:/Company/Company_Environment/makecore/gcc-armhf/bin/arm-linux-gnueabihf-objdump.exe)
set(CMAKE_READELF E:/Company/Company_Environment/makecore/gcc-armhf/bin/arm-linux-gnueabihf-readelf.exe)
set(CMAKE_STRIP E:/Company/Company_Environment/makecore/gcc-armhf/bin/arm-linux-gnueabihf-strip.exe)
set(CMAKE_LINKER E:/Company/Company_Environment/makecore/gcc-armhf/bin/arm-linux-gnueabihf-ld.exe)

其中编译参数CMAKE_TOOLCHAIN_FILE指定如下文件路径即可
在使用库过程中可能会遇到如下问题:
①问题1:链接错误
报错原因和android的问题①相似,添加链接参数-Wl,–start-group $(ABSL_LIBS) -Wl,–end-group
②问题2:无法通信(Server: 开启1234端口、Client:连接localhost:1234端口)
报错原因1:可能 loop 设备没开启
解决方法1:运行下 ifconfig lo up即可。
报错原因2:Linux不支持" localhost:50051 “隐式地址转换
解决方法2:支持显式地址,采用” 0.0.0.0:50051 "代替

Android具体参数可参考官方文档,或者参考这篇文章

 类似资料: