Я разрабатываю библиотеку C++, включая OpenCV, которая будет использоваться в кроссплатформенном решении Xamarin через оболочку и систему упаковки NuGet (см. Этот гид). Я настроил файл CMakeLists.txt
, но я просто не могу правильно скомпоновать OpenCV как для статических (iOS), так и для динамических (Android) библиотек.
Я попытался изменить переменную 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 (.a). Я использую файл цепочки инструментов 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 и использую следующие версии инструментов:
Я надеюсь, что описание моей проблемы достаточно ясное, и заранее благодарю вас за любую помощь.
Вот пример использования готовых библиотек stackoverflow.com/a/64433504/5130269, возможно, это поможет.
Спасибо за ваши ответы. @Tsyvarev Я загрузил OpenCV для Android, установил OpenCV_DIR
в папку jni
и связал цель с libopencv_java4.so
для каждого ABI. Компиляция / компоновка работали, но Xamarin не может загрузить библиотеку (null). Правильны ли эти изменения? Я что-то еще пропустил?
Android: вам необходимо связать с библиотекой OpenCV, которая создана для Android, а не с библиотекой, созданной для вашего хоста. iOS: статическая библиотека не имеет зависимостей с другими библиотеками. При связывании со статической библиотекой вам также необходимо связать ее зависимости.