3

I am integrating existing C++ code that uses OpenCV to an Android app, using Android studio. For this purpose, I have installed the package OpenCV-android-sdk and added it as a module to Android studio. I have also created a simple Kotlin app.

So far I have managed to integrate my C++ code into the project. After adding the paths to the OpenCV includes by means of an include_directories statement, the code compiles successfully.

My next step would be to link against the precompiled OpenCV library, to resolve the "undefined symbol" errors. I have no idea how to achieve this/where to specify it. I have tried to find resources on the web, but not two resources tell the same and the solutions seem overly complicated. I am lost in the jungle.

Andrew T.
  • 4,701
  • 8
  • 43
  • 62
Yves Daoust
  • 672
  • 9
  • Are you getting the undefined symbol errors at runtime, through logcat? If yes, can you post an example? – Florian Echtler Dec 29 '21 at 10:52
  • @FlorianEchtler: there is no run-time, as the app does not build ! –  Dec 29 '21 at 11:01
  • Do you have an example of the build error message, then? – Florian Echtler Dec 29 '21 at 12:19
  • @FlorianEchtler: nothing special, linker error: "C/C++: D:/Sources/OpenCV454/OpenCV-android-sdk/sdk/libcxx_helper/dummy.cpp:20: error: undefined reference to 'cv::Mat::~Mat()'" –  Dec 29 '21 at 13:05
  • I guess, you need to give the opencv's precompiled library path to the compiler somehow. I think this link https://stackoverflow.com/questions/54405275/android-linking-a-external-static-c-c-library-in-android-studio would be helpful. – Harun Cetin Jan 01 '22 at 19:53
  • @HarunCetin: I don't know how to form the path, because the project incorporates four distinct targets (arm, x86, ...) and there are four corresponding .so files. I am sure that the path must include a symbolic name, but I have no idea which nor where. –  Jan 03 '22 at 08:20
  • @YvesDaoust There is a solution here regarding your problem https://stackoverflow.com/questions/17171274/linking-cross-platform-library-to-native-android-application. They used $(TARGET_ARCH_ABI) to define the target platform. I hope it may be helpful. – Harun Cetin Jan 03 '22 at 09:08
  • @HarunCetin: this TARGET_ARCH_ABI is new info, thanks. Unfortunately, the given example is not similar to mine, I don't know exactly where to insert (hack) the symbol definitions nor even how to display their values. The hierarchy of CMakeList, .mk and .cmake files is a total jungle. It is "fun" to see how every solution found on the Web has a different approach. –  Jan 03 '22 at 09:28
  • Could you please post (a minimal, working part of) your code, so that people don't waste time on that? – CristiFati Jan 03 '22 at 11:45
  • @CristiFati: I can't. The app is generated automatically by Android Studio, and is made of hundred files. As regards my own code, a single line with "Mat Test;" is enough. The problem is somewhere in a configuration or makefile, but there are dozens of them organized in folders. –  Jan 03 '22 at 12:17
  • So you create a c++ dll, which you call from Java? why not calling java bindings directly? – CristiFati Jan 03 '22 at 14:03
  • @CristiFati; I need to integrate existing C++ code that uses OpenCV to a Java app. Any method can do. I found no resource that gives a true solution: all that you find relates to older versions, different environments, or is incomplete or does not work, for a variety of reasons. –  Jan 03 '22 at 14:28
  • @YvesDaoust: I think you need to fix your Android.mk and Application.mk, wherever they are stored in Android Studio (this is what I hate about IDEs, you have no idea what happens behind the scenes). You can take inspiration from libjpeg-turbo on how to "ifdef" different targets : https://github.com/openstf/android-libjpeg-turbo/blob/master/jni/vendor/libjpeg-turbo/Android.mk Maybe this helps as well : https://medium.com/android-news/a-beginners-guide-to-setting-up-opencv-android-library-on-android-studio-19794e220f3c – Sdra Jan 04 '22 at 10:28
  • @Sdra: thanks. I hate makefiles, you have no idea what happens behind the scenes. ;-) I mean, it is a pain in the neck to reverse-engineer this bloatware. Fortunately, I eventually solved it. I guess that the app type was a cause. –  Jan 04 '22 at 11:45

1 Answers1

2

I finally managed. Here comes the recipe (validated under Windows).

Make sure to download the OpenCV Android SDK and copy it somewhere.

The project must be created as a Native C++ app (Phone and tablet). A cpp folder is automatically created with a native-lib.cpp source file and a CMakeLists.txt.

Add the following lines to the CMakeLists file, after the project line:

set(OpenCV_DIR $ENV{OPENCV_ANDROID}/sdk/native/jni)
find_package(OpenCV REQUIRED)

You must define the environment variable OPENCV_ANDROID and make it point to the folder .../OpenCV-android-sdk that you copied. (Alternatively, you can hard-code the path in the set command.)

Then insert at the bottom

target_link_libraries(app_name ${OpenCV_LIBS})

where OpenCV_LIBS points to the folder .../OpenCV-android-sdk/sdk/native/libs, and app_name is the name you gave when creating your app.

Finally, cross fingers and build.