【发布时间】:2021-06-26 04:45:37
【问题描述】:
我正在开发一个 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
我希望我的问题描述足够清楚,我提前感谢您的帮助。
【问题讨论】:
-
Android:您需要链接为 Android 构建的 OpenCV 库,而不是为您的主机构建的库。 iOS:静态库不携带与其他库的依赖关系。与静态库链接时,您也需要链接其依赖项。
-
这里是如何使用预建库的示例stackoverflow.com/a/64433504/5130269 可能会有所帮助。
-
感谢您的回复。 @Tsyvarev 我下载了适用于 Android 的 OpenCV,将
OpenCV_DIR设置为jni文件夹,并将每个 ABI 的目标与libopencv_java4.so链接起来。编译/链接有效,但 Xamarin 无法加载库 (null)。这些变化是否正确?还有什么我错过的吗?
标签: c++ ios opencv cmake android-ndk