Как правильно связать OpenCV в кроссплатформенной библиотеке C++ для Android и iOS?

Я разрабатываю библиотеку 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

Ниже приведены команды, которые я использую для создания динамической библиотеки 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). Я использую файл цепочки инструментов 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: вам необходимо связать с библиотекой OpenCV, которая создана для Android, а не с библиотекой, созданной для вашего хоста. iOS: статическая библиотека не имеет зависимостей с другими библиотеками. При связывании со статической библиотекой вам также необходимо связать ее зависимости.

Tsyvarev 30.03.2021 11:42

Вот пример использования готовых библиотек stackoverflow.com/a/64433504/5130269, возможно, это поможет.

Nikolay Khilyuk 30.03.2021 11:55

Спасибо за ваши ответы. @Tsyvarev Я загрузил OpenCV для Android, установил OpenCV_DIR в папку jni и связал цель с libopencv_java4.so для каждого ABI. Компиляция / компоновка работали, но Xamarin не может загрузить библиотеку (null). Правильны ли эти изменения? Я что-то еще пропустил?

Nicolas Zurbuchen 31.03.2021 08:42
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
1
3
61
0

Другие вопросы по теме