4

Yesterday I updated my Android Studio included NDK to version 17.0.4754217and since then I can't run my app anymore. When I tried to rerun the code after the update it gave me the error ABIs [mips64, armeabi, mips] are not supported for platform. Supported ABIs are [armeabi-v7a, arm64-v8a, x86, x86_64] so I excluded them from the project in my app.gradle file the following way: abiFilters 'x86', 'x86_64', /*'armeabi',*/ 'armeabi-v7a', 'arm64-v8a'/*, 'mips', 'mips64'*/.

However, since then I'm having a problem with the C++-file where I use the OpenCV-function cv::CascadeClassifier::detectMultiScale.

It always displays the error: CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o: In function detectAndDisplay(cv::Mat, double, int, std::__ndk1::basic_string<char, std::__ndk1::char_traits<char>, std::__ndk1::allocator<char> >, cv::CascadeClassifier&)': D:\Schule\OpenCV\ARcpp\app\src\main\cpp/native-lib.cpp:158: undefined reference to cv::CascadeClassifier::detectMultiScale(cv::_InputArray const&, std::__ndk1::vector<cv::Rect_<int>, std::__ndk1::allocator<cv::Rect_<int> > >&, double, int, int, cv::Size_<int>, cv::Size_<int>)'.

I call the function like this: cascadeClassifier.detectMultiScale(frame_gray, sights, scaleFactor, minNeighbours, 0 | CV_HAAR_SCALE_IMAGE, Size(30, 30));. The rest of the code is pretty much like shown in the OpenCV-tutorial https://docs.opencv.org/2.4/doc/tutorials/objdetect/cascade_classifier/cascade_classifier.html.

Additionally to the NDK I use CMake and LLDB and my included OpenCV-library is openCVLibrary320. Again, all of this worked until I downloaded the mentioned NDK update.

The rest of the error that always appears on building or executing the app is: Build command failed. Error while executing process C:\Users\chris\AppData\Local\Android\Sdk\cmake\3.6.4111459\bin\cmake.exe with arguments {--build D:\Schule\OpenCV\ARcpp\app\.externalNativeBuild\cmake\debug\arm64-v8a --target native-lib} [1/1] Linking CXX shared library ..\..\..\..\build\intermediates\cmake\debug\obj\arm64-v8a\libnative-lib.so FAILED: cmd.exe /C "cd . && C:\Users\chris\AppData\Local\Android\Sdk\ndk-bundle\toolchains\llvm\prebuilt\windows-x86_64\bin\clang++.exe --target=aarch64-none-linux-android --gcc-toolchain=C:/Users/chris/AppData/Local/Android/Sdk/ndk-bundle/toolchains/aarch64-linux-android-4.9/prebuilt/windows-x86_64 --sysroot=C:/Users/chris/AppData/Local/Android/Sdk/ndk-bundle/sysroot -fPIC -isystem C:/Users/chris/AppData/Local/Android/Sdk/ndk-bundle/sysroot/usr/include/aarch64-linux-android -D__ANDROID_API__=21 -g -DANDROID -ffunction-sections -funwind-tables -fstack-protector-strong -no-canonical-prefixes -Wa,--noexecstack -Wformat -Werror=format-security -std=c++11 -std=c++11 -frtti -fexceptions -O0 -fno-limit-debug-info -Wl,--exclude-libs,libgcc.a -Wl,--exclude-libs,libatomic.a -nostdlib++ --sysroot C:/Users/chris/AppData/Local/Android/Sdk/ndk-bundle/platforms/android-21/arch-arm64 -Wl,--build-id -Wl,--warn-shared-textrel -Wl,--fatal-warnings -LC:/Users/chris/AppData/Local/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/arm64-v8a -Wl,--no-undefined -Wl,-z,noexecstack -Qunused-arguments -Wl,-z,relro -Wl,-z,now -shared -Wl,-soname,libnative-lib.so -o ..\..\..\..\build\intermediates\cmake\debug\obj\arm64-v8a\libnative-lib.so CMakeFiles/native-lib.dir/src/main/cpp/native-lib.cpp.o -llog ../../../../src/main/jniLibs/arm64-v8a/libopencv_java3.so -latomic -lm "C:/Users/chris/AppData/Local/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++_static.a" "C:/Users/chris/AppData/Local/Android/Sdk/ndk-bundle/sources/cxx-stl/llvm-libc++/libs/arm64-v8a/libc++abi.a" && cd ." clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation) ninja: build stopped: subcommand failed.

I`m really lost, hopefully someone knows an answer.

c_steidl
  • 107
  • 2
  • 8
  • I am also getting the same error using latest version 3.4.2 for android. Unable to use 'gnustl_static' as arguments because it is not supported by ndk now. Need help! – Sar Oct 19 '18 at 05:14

5 Answers5

6

OpenCV is built with ANDROID_STL=gnustl_static. After upgrade, your NDK uses the default libc++ instead. You can set ANDROID_STL explicitly in your app/build.gradle:

android { defaultConfig { externalNativeBuild { cmake {
    arguments '-DANDROID_STL=gnustl_static'
} } } }

(see an example here).

Alex Cohn
  • 56,089
  • 9
  • 113
  • 307
  • 'gnustl_static' is no longer supported. Is there any workaround? – Sar Oct 19 '18 at 05:09
  • @Sar: You can rebuild OpenCV with `c++_shared`, or download an older NDK. – Alex Cohn Oct 19 '18 at 05:44
  • 2
    I have no idea how to rebuild OpenCV with c++_shared. If you can provide any references it will be helpful and thanks for the hint – Sar Oct 19 '18 at 05:52
2

When linkin opencv with your project executables, you always have to link with the general library -lopencv_core. But some packages require additional link flags. For example, if you use highgui as in

#include <opencv2/highgui/highgui.hpp>

you must add opencv_highgui link flag for : -lopencv_highgui.

In you case, CascadeClassifiers are defined in

#include "opencv2/objdetect.hpp"

and thus requires a link with opencv_objdetect -lopencv_objdetect.

The solution is to add the link flag -lopencv_objdetect when compiling.

J Dumont
  • 113
  • 6
  • Thank you very much for your response, unfortunately I don't really know how to do this in Android Studio. – c_steidl May 13 '18 at 17:50
  • I just noticed that I already `#include ` included in my C++-code. Is that what you meant? Because adding/removing it makes no difference considering the above mentioned error. – c_steidl May 13 '18 at 20:19
1

A more complete answer for all the seekers out there. Using OpenCV prebuilt static libraries in your project with a native component.

This is what I have for the build.gradle:

defaultConfig {
    minSdkVersion 21
    targetSdkVersion 21
    externalNativeBuild {
        cmake {
            cppFlags "-fexceptions -std=gnu++11"
            arguments '-DANDROID_STL=gnustl_static'
        }
    }
    ndk {
        // Specifies the ABI configurations of your native
        // libraries Gradle should build and package with your APK.
        abiFilters 'armeabi-v7a', 'x86'
        stl = "gnustl_shared"
    }
}

This is the CMakeLists.txt:

set(OPENCV_LIBRARIES ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libopencv_video.a
                     ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libopencv_imgproc.a
                     ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libopencv_core.a
                     ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libopencv_highgui.a
                     ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libtbb.a
                     ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libcpufeatures.a
                     )

if (${ANDROID_ABI} STREQUAL "x86")
    set(OPENCV_LIBRARIES ${OPENCV_LIBRARIES}
                         ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libippiw.a
                         ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libippicv.a
                         ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libittnotify.a
                         )
    set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -Wl,--exclude-libs,libippicv.a -Wl,--exclude-libs,libippiw.a")
endif()

if (${ANDROID_ABI} STREQUAL "armeabi-v7a")
    set(OPENCV_LIBRARIES ${OPENCV_LIBRARIES}
                         ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_NDK_ABI_NAME}/libtegra_hal.a
                         )
endif()

(then use ${OPENCV_LIBRARIES} for your target_link_libraries)

Roy Shilkrot
  • 3,079
  • 29
  • 25
1

The first comment on this link can save you many hours which I copy past below:

"I had similar issue. In turned out that you got to use similar Android NDK as one that was used to build OpenCV Android SDK, that in case of versions ~3.4 is Android NDK 10. Recently, OpenCV Android SDK 4.0.1 have been released and it works with the newest NDK version (19 at the time)."

At the time of this post, you can find the release 4.1.2. You can check if there's a latest release on this link.

After you select your latest version, in this case 4.1.2, download the file opencv-4.1.2-android-sdk.zip, unzip it and copy the sdk/native folder to yourprojectfolder/your-app/src/sdk/.

You're ready to roll.

Eduardo Pinheiro
  • 3,409
  • 3
  • 30
  • 39
0

I solved this problem by using mix with this OpenCV + contrib lib (opencv4_1_0_contrib) and official Java OpenCV classes (4.3). Successfully run official OpenCV FaceDetection example on Android 9.


Some usefull code:

App level build.gradle:

android{defaultConfig{
//...
externalNativeBuild {
            cmake {
                cppFlags "-frtti -fexceptions"
                abiFilters 'x86', 'x86_64', 'armeabi-v7a', 'arm64-v8a'
                //I import OpenCV as module and provide it path to CMake
                arguments "-DOpenCV_DIR=/" + rootProject.projectDir.path + "/sdk/native"
             }
        }
}}

externalNativeBuild {
        cmake {
            path "src/main/cpp/CMakeLists.txt"
            version "3.10.2"
        }
    }

My CMakeLists.txt:

# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)

#Add OpenCV 4 lib
include_directories(${OpenCV_DIR}/jni/include) #Path from gradle to OpenCV Cmake
add_library( lib_opencv SHARED IMPORTED )
set_target_properties(lib_opencv PROPERTIES IMPORTED_LOCATION ${OpenCV_DIR}/libs/${ANDROID_ABI}/libopencv_java4.so)

#Add Your Native Lib
add_library(native-lib SHARED native-lib.cpp)
add_library(detection_based_tracker SHARED detectionbasedtracker_jni.cpp)

#Add&Link Android Native Log lib with others libs
find_library(log-lib log)
target_link_libraries(detection_based_tracker lib_opencv ${log-lib})

NDK version was 21.0.611669. Also I don't use arguments for CMake like -DANDROID_STL=gnustl_static.