title: How to properly link OpenCV in a C++ cross-platform library for Android and iOS?
body: <p>I am developing a C++ library, including OpenCV, which will be used in a cross-platform Xamarin solution through a wrapper and the NuGet packaging system (see this <a href="https://docs.microsoft.com/en-us/xamarin/cross-platform/cpp/" rel="nofollow noreferrer">guide</a>). I configured a <code>CMakeLists.txt</code> file but I simply cannot get OpenCV to be correctly linked for both static (iOS) and dynamic (Android) libraries.</p>
  <p>I tried to change the <code>OpenCV_DIR</code> variable, install and build OpenCV from sources and manually include the content of the <code>OpenCV_INCLUDE_DIRS</code> variable but nothing worked. I also noticed that the linking works when only using <code>cv::Point</code>. But the linking does not work when using <code>cv::Mat</code>, which I do not understand the reason.</p>
  <p>The following is the <code>CMakeLists.txt</code> that I am using :</p>
  <pre><code>cmake_minimum_required (VERSION 3.2)
  project (MyLib C CXX)
  enable_testing()
  
  set(CMAKE_CXX_FLAGS &quot;${CMAKE_CXX_FLAGS} -std=c++11&quot;)
  MESSAGE(STATUS &quot;CMAKE_CXX_FLAGS: &quot; ${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 &quot;OpenCV_INCLUDE_DIRS = ${OpenCV_INCLUDE_DIRS}&quot;)
  message(STATUS &quot;OpenCV_LIBS = ${OpenCV_LIBS}&quot;)
  message(STATUS &quot;OpenCV_DIR = ${OpenCV_DIR}&quot;)
  include_directories(${OpenCV_INCLUDE_DIRS})
  target_link_libraries(MyLib ${OpenCV_LIBS})
  </code></pre>
  <p>The following shows the location of OpenCV's files that are used during the build process. Everything seems alright.</p>
  <pre><code>-- 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
  </code></pre>
  <h3>Android</h3>
  <p>The following is the commands that I am using to build the Android dynamic library (.so). I have installed the NDK and am building for each ABI (x86, x86_64, armeabi-v7a, arm64-v8a).</p>
  <pre><code>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
  </code></pre>
  <p>I directly get an error when building the library which is the following.</p>
  <pre><code>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)
  </code></pre>
  <h3>iOS</h3>
  <p>The following is the commands that I am using to build the iOS static library (.a). I am using leetal's ​cmake toolchain file from this <a href="https://github.com/leetal/ios-cmake" rel="nofollow noreferrer">repository</a>.</p>
  <pre><code>cmake ../.. -G Xcode -DCMAKE_TOOLCHAIN_FILE=../../ios.toolchain.cmake -DPLATFORM=OS64COMBINED -DBUILD_SHARED_LIBS=OFF
  cmake --build . --config Release
  </code></pre>
  <p>The compilation of the static library seems to work because no error message is printed. However, when the library is used in the final Xamarin solution, the linked library cannot be found and the following error is shown.</p>
  <pre><code>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)
  </code></pre>
  <h3>Question</h3>
  <p>What am I missing in order to properly compile and link OpenCV into my C++ library ?</p>
  <p>I am working on macOS Big Sur and uses the following tools versions:</p>
  <ul>
  <li>cmake : 3.20.0-rc5</li>
  <li>ndk : 23.0.7196353</li>
  <li>apple clang : 12.0.0</li>
  </ul>
  <p>I hope that the description of my problem is clear enough and I thank you in advance for any help.</p>