Android Studio CMake 引入静态包.a 以OpenCV为例

20 篇文章 0 订阅
8 篇文章 0 订阅

以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

参考:c - How to link Zlib with Cmake - Stack Overflow

2.报AMedia相关的错误。undefined symbol: AMediaExtractor_new

解决方案:

链接库加 mediandk

如果还遇到错误,参考:android - mediaNdk undefined reference to 'AMediaCodec_signalEndOfInputStream' - Stack Overflow

3.报openCV相关错误。undefined reference to 'cv::waitKey(int)'

这个比较草蛋(一种蛋)。。。明明官方的.a文件都引入了。

搜了下资料原来是编译顺序的问题,C++与Java不一样。

你需要在链接库的时候,把最核心的core,放到最后,最起码放到报错的imgproc这些后面:

参考:undefined reference to cv::softdouble::operator/ - OpenCV Q&A Forum

4.报不知名错误:  ld: error: undefined symbol: __write_chk

原因是NDK版本不一致,你当前编辑器的NDK版本与.a的不一致。

解决方案:

(1)尝试降低/升高你的NDK版本。(参考了error: undefined reference to __write_chk错误_深大村名的博客-CSDN博客

(2)拿源码重新编译你当前版本NDK的.a静态库。

后一个方案适合大佬,我不是别问我怎么编译。。。问C++造轮子的工程师,他们很熟悉。

关于如何正确改变NDK版本我也给你找好了:(图出自:Invalid revision: 3.18.1 CMake in Android Studio - Stack Overflow

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包了。

每个人因为环境代码不同肯定会遇到不同的问题,本篇文章不一定能解决您全部的问题。

但尽管如此,我也掉了好多头发。。。我本可以不分享出来的,生活不易,希望能让国内的开发者少走弯路。

故,侵究。

  • 4
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值