Android中用CMake集成OpenCV3.1.0与dlib遇未定义引用错误
嘿,这种链接错误我太熟了!单独跑OpenCV没问题,一加dlib就报undefined reference,大概率是CMake配置里的库依赖顺序或者dlib的编译选项没弄对。给你几个实用的解决方案:
1. 调整库的链接顺序
链接器是按你写的顺序处理库的,如果dlib依赖OpenCV的函数,那必须把OpenCV的库放在dlib前面链接。举个例子,你的target_link_libraries应该写成这样:
target_link_libraries( your-native-lib # 替换成你的native库名称 ${OpenCV_LIBS} # 先链接OpenCV所有依赖库 dlib # 再链接dlib )
之前如果是先写dlib再写OpenCV,链接器会先处理dlib,这时候它找不到OpenCV的符号,就会报错。反过来顺序就对了。
2. 确认dlib编译时启用了OpenCV支持
如果你是自己编译的dlib库,一定要在编译dlib的时候开启DLIB_USE_OPENCV选项。比如在dlib的CMakeLists里加上:
set(DLIB_USE_OPENCV ON) find_package(OpenCV REQUIRED) include_directories(${OpenCV_INCLUDE_DIRS})
要是你用的是预编译的dlib包,得确认这个包是带OpenCV支持编译出来的——有些预编译包默认没开这个选项,自然找不到OpenCV的符号。
3. 明确指定OpenCV需要的模块
OpenCV3.1.0的模块很多,有时候find_package(OpenCV REQUIRED)可能没包含全必要的模块。fastFree是core模块里的函数,你可以明确指定要链接的模块:
find_package(OpenCV REQUIRED COMPONENTS core imgproc) # 根据你的需求添加其他模块
这样能确保CMake准确找到并链接包含fastFree的core库。
4. 清理缓存后重新构建
有时候Android Studio的缓存会搞事情,建议先删除项目根目录下的.cxx文件夹和app/build文件夹,然后点击File -> Sync Project with Gradle Files,再重新编译。缓存残留的旧配置很容易导致这种奇怪的链接错误。
额外调试技巧
你可以用nm命令检查库的符号:
- 检查OpenCV的core库是否包含
fastFree:nm -D path/to/your/opencv/libs/armeabi-v7a/libopencv_core.so | grep fastFree
如果能输出类似0001234 T cv::fastFree(void*)的内容,说明OpenCV库是正常的。
- 再检查dlib库是否引用了这个符号:
nm -D path/to/your/dlib/libdlib.so | grep fastFree
如果能看到U cv::fastFree(void*),说明dlib确实需要这个符号,那回到前面的链接顺序和dlib编译选项排查就行。
内容的提问来源于stack exchange,提问作者Yusuf Çelebi

