以OpenCV为例,记录开发过程并附上部分踩坑细节
1.引入openCV的.a包,官方SDK目录如下:
记得第三方也要引入。引入后的样子如下:
你会发现,x86和arm的包不太一样。
2.引入OpenCV头文件.h .hpp
首先,在你的cpp/include下,加入openCV的头文件,如下图:
官方SDK在这里:
3.CMake引入.a及你自己的c++源码
先引入头文件:
set(libs ${CMAKE_SOURCE_DIR}/..)
include_directories(${libs}/cpp/include/opencv2)
set(target xxx) # 打包的名字
cmake语法就不在这里赘述了。。。
上面一堆.a文件,一个个引入,引入的写法在下面:(以最重要的core为例)
add_library(core STATIC IMPORTED)
set_target_properties(core
PROPERTIES IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI}/libopencv_core.a)
最终呈现的链接库是这样的:
带劲不。。。
踩坑记录:
1.报zlib的错误,缺少gzputs相关的,open、close什么的。undefined symbol: gzputs
解决方案:
CMake加 find_package(ZLIB)
链接库加 ZLIB::ZLIB
参考:https://stackoverflow.com/questions/53298492/how-to-link-zlib-with-cmake/56886808
2.报AMedia相关的错误。undefined symbol: AMediaExtractor_new
解决方案:
链接库加 mediandk
如果还遇到错误,参考:https://stackoverflow.com/questions/45251937/mediandk-undefined-reference-to-amediacodec-signalendofinputstream
3.报openCV相关错误。undefined reference to 'cv::waitKey(int)'
这个比较草蛋(一种蛋)。。。明明官方的.a文件都引入了。
搜了下资料原来是编译顺序的问题,C++与Java不一样。
你需要在链接库的时候,把最核心的core,放到最后,最起码放到报错的imgproc这些后面:
参考:https://answers.opencv.org/question/186124/undefined-reference-to-cvsoftdoubleoperator/
4.报不知名错误: ld: error: undefined symbol: __write_chk
原因是NDK版本不一致,你当前编辑器的NDK版本与.a的不一致。
解决方案:
(1)尝试降低/升高你的NDK版本。(参考了https://blog.csdn.net/printf123scanf/article/details/106136741)
(2)拿源码重新编译你当前版本NDK的.a静态库。
后一个方案适合大佬,我不是别问我怎么编译。。。问C++造轮子的工程师,他们很熟悉。
关于如何正确改变NDK版本我也给你找好了:(图出自:https://stackoverflow.com/questions/66540676/invalid-revision-3-18-1-cmake-in-android-studio)
cmake换成NDK,那个“-”别乱点,如果点乱了确定会给你提示,点cancel重来哈。别怪我没提醒你。。。(擦眼泪)
记得build.gradle也要改哈:ndkVersion = 'yours'
5.差不多能跑起来了,,,会报一个x86的错误。
解决方案:
在gradle的defaultConfig里加
ndk {
abiFilters 'armeabi-v7a', 'arm64-v8a'
}
arm就够你用了。。。如果真有x86需求的话,上面就说了openCV针对x86的指令集做了兼容,那么你的CMake就需要兼容,咋兼容等我有这个需求了再补充哈。(狗头保命)
声明一下这边是:opencv2,so包是libopencv_java4.so
一般情况下这种知名的第三方都不会随便改的,所以一般是NDK19。
在开发过程中,高版本的NDK会让你兼容,在gradle的cmake加 arguments "-DANDROID_STL=c++_shared"。
这样的话,编译动态库会有libc++.so,更换19可以去掉,这样就只打一个so包了。
每个人因为环境代码不同肯定会遇到不同的问题,本篇文章不一定能解决您全部的问题。
但尽管如此,我也掉了好多头发。。。我本可以不分享出来的,生活不易,希望能让国内的开发者少走弯路。
故,侵究。