如何在适用于 Android 和 iOS 的 C++ 跨平台库中正确链接 OpenCV?

时间:2021-03-30 07:18:24

标签: c++ ios opencv cmake android-ndk

我正在开发一个 C++ 库,包括 OpenCV,它将通过包装器和 NuGet 打包系统在跨平台 Xamarin 解决方案中使用(请参阅此 guide)。我配置了一个 CMakeLists.txt 文件,但我根本无法为静态 (iOS) 和动态 (Android) 库正确链接 OpenCV。

我尝试更改 OpenCV_DIR 变量,从源代码安装和构建 OpenCV,并手动包含 OpenCV_INCLUDE_DIRS 变量的内容,但没有任何效果。我还注意到仅使用 cv::Point 时链接有效。但是使用 cv::Mat 时链接不起作用,我不明白原因。

以下是我正在使用的 CMakeLists.txt

cmake_minimum_required (VERSION 3.2)
project (MyLib C CXX)
enable_testing()

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
MESSAGE(STATUS "CMAKE_CXX_FLAGS: " ${CMAKE_CXX_FLAGS})

# Source and headers files
set(SOURCES File1.cpp File2.cpp)
set(HEADERS File1.h File2.h)

# Library
if(BUILD_SHARED_LIBS)
  add_library (MyLib SHARED ${SOURCES} ${HEADERS})
  target_compile_definitions(MyLib PUBLIC IS_BUILDING_SHARED)
else()
  add_library (MyLib STATIC ${SOURCES} ${HEADERS})
endif()

# Dependencies
set(OpenCV_DIR /usr/local/Cellar/opencv/4.5.0_1/lib/cmake/opencv4)
find_package(OpenCV REQUIRED)
message(STATUS "OpenCV_INCLUDE_DIRS = ${OpenCV_INCLUDE_DIRS}")
message(STATUS "OpenCV_LIBS = ${OpenCV_LIBS}")
message(STATUS "OpenCV_DIR = ${OpenCV_DIR}")
include_directories(${OpenCV_INCLUDE_DIRS})
target_link_libraries(MyLib ${OpenCV_LIBS})

以下显示了在构建过程中使用的 OpenCV 文件的位置。一切似乎都很好。

-- OpenCV_INCLUDE_DIRS = /usr/local/Cellar/opencv/4.5.0_1/include/opencv4
-- OpenCV_LIBS = opencv_calib3d;opencv_core;opencv_dnn;opencv_features2d;opencv_flann;opencv_gapi;opencv_highgui;opencv_imgcodecs;opencv_imgproc;opencv_ml;opencv_objdetect;opencv_photo;opencv_stitching;opencv_video;opencv_videoio;opencv_alphamat;opencv_aruco;opencv_bgsegm;opencv_bioinspired;opencv_ccalib;opencv_datasets;opencv_dnn_objdetect;opencv_dnn_superres;opencv_dpm;opencv_face;opencv_freetype;opencv_fuzzy;opencv_hfs;opencv_img_hash;opencv_intensity_transform;opencv_line_descriptor;opencv_mcc;opencv_optflow;opencv_phase_unwrapping;opencv_plot;opencv_quality;opencv_rapid;opencv_reg;opencv_rgbd;opencv_saliency;opencv_sfm;opencv_shape;opencv_stereo;opencv_structured_light;opencv_superres;opencv_surface_matching;opencv_text;opencv_tracking;opencv_videostab;opencv_viz;opencv_xfeatures2d;opencv_ximgproc;opencv_xobjdetect;opencv_xphoto
-- OpenCV_DIR = /usr/local/Cellar/opencv/4.5.0_1/lib/cmake/opencv4

安卓

以下是我用来构建 Android 动态库 (.so) 的命令。我已经安装了 NDK 并且正在为每个 ABI(x86、x86_64、armeabi-v7a、arm64-v8a)构建。

cmake ../.. -DCMAKE_TOOLCHAIN_FILE=/Users/$USER/Library/Android/sdk/ndk-bundle/build/cmake/android.toolchain.cmake -DANDROID_NATIVE_API_LEVEL=21 -DANDROID_ABI=$abi_name -DBUILD_SHARED_LIBS=ON
cmake --build . --config Release

我在构建库时直接得到一个错误,如下所示。

ld: error: /usr/local/Cellar/opencv/4.5.0_1/lib/libopencv_gapi.4.5.0.dylib: unknown file type
ld: error: /usr/local/Cellar/opencv/4.5.0_1/lib/libopencv_stitching.4.5.0.dylib: unknown file type
[...]
ld: error: /usr/local/Cellar/opencv/4.5.0_1/lib/libopencv_rapid.4.5.0.dylib: unknown file type
ld: error: too many errors emitted, stopping now (use -error-limit=0 to see all errors)
clang++: error: linker command failed with exit code 1 (use -v to see invocation)

iOS

以下是我用来构建 iOS 静态库 (.a) 的命令。我正在使用此 repository 中的 leetal cmake 工具链文件。

cmake ../.. -G Xcode -DCMAKE_TOOLCHAIN_FILE=../../ios.toolchain.cmake -DPLATFORM=OS64COMBINED -DBUILD_SHARED_LIBS=OFF
cmake --build . --config Release

静态库的编译似乎可以工作,因为没有打印错误消息。但是,在最终的 Xamarin 解决方案中使用该库时,找不到链接的库并显示以下错误。

Native linking failed, undefined symbol: cv::Mat::deallocate(). Please verify that all the necessary frameworks have been referenced and native libraries are properly linked in. (MT5210)

问题

为了正确编译 OpenCV 并将其链接到我的 C++ 库中,我缺少什么?

我正在使用 macOS Big Sur 并使用以下工具版本:

  • cmake : 3.20.0-rc5
  • ndk:23.0.7196353
  • 苹果叮当声:12.0.0

我希望我的问题描述足够清楚,我提前感谢您的帮助。

0 个答案:

没有答案