快速开始
一、创建android编译目录,在grpc源码根目录下运行:
mkdir -p cmake/build_android && cd cmake/build_android
二、cmkae生成对应Makefile等编译所需的文件
cmake
-DCMAKE_TOOLCHAIN_FILE=/zhuyazhou/DDS/tools_dds/android-ndk-r25/build/cmake/android.toolchain.cmake
-DANDROID_ABI=arm64-v8a -DCMAKE_INSTALL_PREFIX=/grpc_cross_build/android_install -DANDROID_PLATFORM=android-28 -DCMAKE_BUILD_TYPE=Release -DgRPC_BUILD_TESTS=OFF -DBUILD_SHARED_LIBS=ON -DANDROID_STL=c++_shared -B . -S …/…/
三、注意事项:
- -DANDROID_PLATFORM=android-28指定android版本是28,可以根据具体项目修改。如果此配置型进行了修改,也需要对应将CMakeLists.txt中gpr库链接的ndk的liblog库绝对路径同步修改为具体版本的so库路径。
- -DCMAKE_INSTALL_PREFIX=/grpc_cross_build/android_install指定make install安装的路径,可以根据需要修改到其它所需路径。如果此配置型进行了修改需要搞将CMakeLists.txt中strip_genarated_lib_android 对应的COMMAND路径
- -DANDROID_STL=c++_shared 不添加这句话,会导致不明原因的报错,如下:
terminating with uncaught exception of type std::bad_cast: std::bad_cast - 因为ndk设置了CMAKE_FIND_ROOT_PATH_MODE_LIBRARY为ONLY就会导致找不到库的问题,具体原因如下:链接
特别地,对于交叉编译环境来说,一般通常会设置CMAKE_FIND_ROOT_PATH_MODE_LIBRARY为ONLY:
SET(CMAKE_FIND_ROOT_PATH_MODE_PROGRAM NEVER)
SET(CMAKE_FIND_ROOT_PATH_MODE_LIBRARY ONLY)
SET(CMAKE_FIND_ROOT_PATH_MODE_INCLUDE ONLY)
此时由于设置了CMAKE_FIND_ROOT_PATH_MODE_LIBRARY为ONLY,则此后面使用find_library寻找第三方库的时候,不论是否传入了路径,也不论是否设置了CMAKE_PREFIX_PATH,都无法找到,因为此时find_library只会从CMAKE_FIND_ROOT_PATH设置的路径中寻找。此时如果想用find_library找到第三方库,要么将CMAKE_FIND_ROOT_PATH_MODE_LIBRARY 设置为NEVER,要么将第三方库路径添加到CMAKE_PREFIX_PATH中(推荐添加到CMAKE_PREFIX_PATH)。对于CMAKE_FIND_ROOT_PATH_MODE_INCLUDE 之于find_path,同样的道理。
- 两个命令:
1)file xxx.so 可以准确看到编译后的文件格式是否arm
2)readelf -d xxx.so 可以看到相关链接的库有哪些
以上就是本次交叉编译所遇到的问题和总结。
于成都,2023年7月17日。