For a number of different reasons, you might want/need to build OpenCV from scratch instead of using the pre-built and official libraries provided by OpenCV. Since you’ve ended up reading this post, there’s a good chance that you already know why you might need to do this, but if you don’t, you can check out my similar post from a couple of years ago for some answers on this. That post was based on OpenCV 3.3 which is considered out-of-date these days, especially with OpenCV 4 out in the market (OpenCV 4.0.1 at the time of writing this article), so I decided to write a new tutorial to address some of the differences. So without without further ado, here we go.
Please note that this tutorial is written with Windows users in mind but you should be able to build with “almost” the same steps under Linux and macOS as well. You just need to convert the steps with MinGW to default make command in Linux/Unix.
First things first, the prerequisites for building OpenCV 4.x for Android are:
- OpenCV 4.x source codes of course (You can get them here in a zip file if you choose sources instead of pre-built binaries or you can clone then from here, I’ll use OpenCV 4.0.1 just for reference)
- CMake (Get the latest version from CMake website, I’ll use CMake 3.13.3)
- Get MinGW (If you’re a Qt fan and you want to use it for building Android app, Qt installer includes MinGW by default so you can use that one, otherwise refer to the official MinGW website to get it)
- Android Studio (It’s available here, download the latest version available.)
- Use SDK manager in Android Studio to get the latest Android SDK and NDK
Important note for OpenCV version 4.0.1 prerequisites: You’ll need Android NDK Revision 16b for properly building this particular version of OpenCV and you might face issues if you use a version of NDK higher that the one we mentioned. You can get individual Android NDK revisions from here.
Here is a question that is usually skipped in tutorials, so for those of you who are interested in understanding the whole process, we’re going to ask it and try to provide some clear but brief answers for it.
What is the purpose of each one of the prerequisites?
Let’s start with CMake, it allows us to create projects out of source codes and build them using our favorite IDEs or make/build systems. We’ll be using CMake to create MinGW Makefiles that can be built with MinGW make system and Android armv7 cross-compilers. So, we’ll be using MinGW as the make system. Android Studio on the other hand is not directly used for building OpenCV but it includes an easy way of installing Android SDK and NDK and managing different installations and versions of the SDK, using its built-in SDK Manager. Finally, SDK and NDK contain all the required source codes, headers, compilers and literally everything needed for building apps for Android.
That’s a very brief explanation but it contains enough keywords in case you want to dig deeper and learn more about each one of them. So, assuming you’ve got all the prerequisites on your computer, we can start by running CMake and choosing the OpenCV source codes folder for “Where is the source code” and then choose a build folder, preferably under the same path, and preferably call it “build_android” for “Where to build the binaries”.
Then press the “Configure” button. This will take you to the configuration page. Select “MinGW Makefiles” for the generator and press “Next”.
In the next page, we need to choose the right Toolchain for cross-compiling OpenCV for Android. To do this you have to choose the “android.toolchain.cmake” file which can be found under OpenCV source codes folder and inside “platforms/android” as seen in the following screenshot:
This will start a CMake configuration which might end up with some errors, but don’t worry about it, what you have to do is adding a few entries manually and making sure that MinGW is in the PATH environment variable. You can manually add entries to CMake by using the “Add Entry” button and entering the “Name”, “Type” and “Value” of the entry. Here is an example:
So start by adding the following entries:
- Add “ANDROID_NDK” with a type of “PATH” and value of Android NDK path (Note that for OpenCV 4.0.1 this must be Android NDK r16b)
- Add “ANDROID_SDK_ROOT” with a type of “PATH” and value to Android Sdk root folder
- Add “ANDROID_NATIVE_API_LEVEL” with a type of “PATH” and value of “27”
Press “Configure” again and you’ll notice a longer configuration taking place and if everything goes well you should not receive any errors. You’re ready to press “Generate” now, but if you want you can use the following options as well to further customize your OpenCV build:
- Disable BUILD_ANDROID_PROJECTS
- Disable BUILD_ANDROID_EXAMPLES
- Disable BUILD_PERF_TESTS
- Disable BUILD_TESTS
Android libraries are built statically by default but if you want the *.so file and a dynamic build (which is the recommended route for developers that want to integrate OpenCV and Qt framework), then you can enable BUILD_SHARED_LIBS to build the shared/dynamic libraries instead of the static ones. Note that enabling shared libs when building OpenCV for Android, will force you to disable BUILD_FAT_JAVA_LIB as well, so just make sure the checkbox next to it is unchecked and press generate to get the project files.
The last step is to actually build the OpenCV libraries so you can start that by opening up a command prompt instance and switching to the OpenCV build folder that you had set in CMake and type the following command:
mingw32-make.exe
You need to be patient for the OpenCV libraries to be built. After the build is done, you can use need to execute the following command to get the nicely packed OpenCV 4.x library inside the install folder:
mingw32-make.exe install
And that should be it. Make sure to post your comments and questions below in case you face issues following the steps above.
Hey,
I generated makefiles using the cmake gui tool.
Using mingw32-make is giving errors regarding syntax between c++98 and c++14.
So I opened the opencv source code as cmake project in Qt5.12.
After compilation i get only dlls but no so.
Any suggestions?
First of all, you don’t need Qt for this.
Second, if you’re using native libs you only need libraries anyway (you shouldn’t get DLL files though, you should get Android native library files)
Hey,
Some updates for people struggling with 4.5.2:
-Build from the source using NDK 21e
-Do NOT use the toolchain file included with OpenCV 4.5.2, that’s obsolete and will fail with any NDK after 15. Instead, use the toolchain in the NDK’s build folder.
For those eventually making an .so with Visual Studio:
-Do NOT use the GNU static library, use the LLVM static library instead
-Put the library files in “Library Dependences” instead of “Additional Dependencies” — otherwise it won’t find them. This will at least get the .so to compile successfully.
Thanks for sharing this. I guess compiling OpenCV was the biggest obstacle. Does this mean you got it working?
I will try to put aside some time in the upcoming days to write a new article explaining the use of recent OpenCV versions in recent Unity versions.
Almost. Let’s say I got it as far as the native wrapper for the face reading working, but even when I copy the xml cascade file to the persistent data path for android, the native code tries to read it from that path and fails for some reason, and I could swear this exact code was working with 4.0.1.
Can you please share more info. I am struggling to build this.
I successfully built Opencv using you tutorial, but at the end I was expecting to find the “libopencv_java4.so”, that I need in Android Studio.
But inside the “install” folder I found only .dll file:
– libopencv_core420.dll
– libopencv_features2d420.dll
– libopencv_flann420.dll
– libopencv_highgui420.dll
etc…
How can I use these files?
How can I get the .so file?
As the title says, this tutorial is for “Native” Android Development so you’ll only get C++ libs.
You can download Java libs from OpenCV website directly. Zero hassle.
Hi,
I did as mentioned in both tutorials, but now I failed to load the library in Android studio.
Please HELP!
Can you share more info?
Hi,
While trying with 4.3.0 I had problems because of my java version(13) and gradle.
after 4 days I preferred to try with 3.4.5 and it was successful after two builds.
There is some problem with 4.* version.
P.S:
I need also the java bindings/wrappers.
I build it, but dont know how to integrate it in Android Studio.
I appreciate if you can publish some tutorial about it.
Glad you figured it out. I’ll make sure to write about it sometime.
Hello Amin, and thanks for this wonderful tutorial, it’s been very helpful.
I have an issue on the last step with MinGW. When I run “mingw32-make.exe”, on the 63% it reports and error:
C:\opencv-install\opencv\sources\modules\core\src\utils\logtagconfigparser.cpp: In static member function ‘static std::string cv::utils::logging::LogTagConfigParser::toString(cv::utils::logging::LogLevel)’:
C:\opencv-install\opencv\sources\modules\core\src\utils\logtagconfigparser.cpp:301:16: error: ‘to_string’ is not a member of ‘std’
return std::to_string((int)level);
^
C:\opencv-install\opencv\sources\modules\core\src\utils\logtagconfigparser.cpp:303:1: error: control reaches end of non-void function [-Werror=return-type]
}
^
I’m using:
– Android NDK 16b
– OpenCV 4.1.2
Thanks!
Try a higher version of NDK. As I mentioned in the tutorial, “for OpenCV 4.0.1 this must be Android NDK r16b”. For OpenCV 4.1.2 you need to figure it out on your own but I guess a higher version will help.
Hi,
I’m a bit late to the party but was hoping you could help me with the following:
I’ve managed to build OpenCV without an issue, but the binaries that are produced are over 4 times BIGGER than the original ones provided in the SDK – despite me having removed a lot of the packages that are linked internally…
I’ve tracked it down to having the BUILD_SHARED_LIBS setting on or off, if it’s ON the binary is very small, but when my app starts i get a popup asking me to “Install missing Packages” – when it’s OFF i get huge binaries, but my app works!
Any ideas how i can get small binaries and have no need to install extra packages?
Thanks,
David
Sorry correction on the above, the message that appears in the form of a dialog says:
Title: “Package not found”
Message: “OpenCV Manager package was not found! Try to install it?”
Are you developing a Native app? In other words, Java or C++?!
Java, for use in Android.
But i think i figured it out, instead of using MinGW Makefiles i swapped to a later version of the NDK (20) and that includes Ninja for builds. This has a command that lets you strip ” ninja install/strip” (what it strips im not sure) , but running with this reduced my binary build size (with BUILD_SHARED_LIBS=OFF) from 43MB to 7MB for an arm64-v8a architecture.
Glad you figured it out and thanks for sharing the solution here.
Thanks!
For the complete solution that i came up with, please have a look at the script and guide here:
https://gist.github.com/david-serrano/359b4ca3df2aeb31eca224990ba486f2
Hello Amin ?
// what I did
I built the OpenCV Libraries for Android on Windows as you described here:
https://amin-ahmadi.com/2019/02/03/how-to-build-opencv-4-x-for-native-android-development
And then tried to add them to a Qt project like you described here:
http://amin-ahmadi.com/2015/06/23/opencv-qt-android-adding-required-libraries-and-includes
But I wasn’t able to do the last two steps.
// the problem
A couple of files are missing me like “libopencv_java.so” as well as “libopencv_info.so”
Which you included in your PRI file (in the last link I added).
Do you know why they are missing or where to find them ? ?
// note
While I was building from the source files in CMake I unchecked the following:
– BUILD_ANDROID_PROJECTS
– BUILD_ANDROID_EXAMPLES
– BUILD_PREF_TESTS
– BUILD _TESTS
and checked BUILD_SHARED_LIBS
without unckecking BUILD_FAT_JAVA_LIB manually (I don’t know if CMake does this automatically)
After that everything went normally with mingw32-make.exe and mingw32-make.exe install (no error messages).
I can include the libs in Qt for an Android project but I keep getting this error message:
–GOOGLE_DRIVE_LINK_REMOVED–
and this is my pro file:
–GOGLE_DRIVE_LINK_REMOVED–
Additionally I uploaded the whole OpenCV folder here:?
–GOOGLE_DRIVE_LINK_REMOVED–
Best Regards
Try building OpenCV world as described in that post and simply use something similar to the following to add OpenCV to a Qt Android project:
android: {
ANDROID_PACKAGE_SOURCE_DIR = $$PWD/android
INCLUDEPATH += "C:/opencv/sdk/native/jni/include"
LIBS += -L"C:/opencv/sdk/native/libs/armeabi-v7a" -l"opencv_world"
}
Don’t forget to add libopencv_world.so file to the $$PWD/android/libs/armeabi-v7a path as well.
To be clear, $$PWD is where your source codes reside.
Ok thank you very much, one more question please..
can I use the built OpenCV libraries now for Android devices with architecture armeabi v8a or x86(on Android emulators)?
And isn’t the OpenCV-Android-SDK only for Java applications, or you can use it also in C++ applications on Android?
You can use Android build for the architecture you build for. If you build for armeabi then you can use it for armeabi and so on.
As for your second question, no OpenCV is not (and never was) just for Java. In fact it is just for C++ with wrappers for other languages such as Java, Python and so on.
(Sorry but the last reply seems to have disappeared…?)
Hi! Thanks for your wonderful article! I compiled it and successfully get several `.so` files in `…installsdknativelibsarmeabi-v7a` such as `libopencv_calib3d.so` and so on. However, when importing into Android Studio and compile, the following error occurs. I suspect that I got the wrong ABI, and by the method in https://stackoverflow.com/questions/22620667/how-to-determine-abi-of-android-so-file-i-e-armeabi-or-armeabi-v7a, I got the following output, which is different from the pre-compiled OpenCV4Android `.so` files downloaded from official website. Output of mine and theirs are both pasted at the end of this comment.
Thank you very much for spending your precious time reading this comment. I am eagerly looking forward to hearing from you!
```
Build command failed.
Error while executing process ...cmake.exe with arguments ... error adding symbols: File in wrong format
clang++.exe: error: linker command failed with exit code 1 (use -v to see invocation)
ninja: build stopped: subcommand failed.
```
My `.so` compiled by this article:
```
File Attributes
Tag_CPU_name: "cortex-a8"
Tag_CPU_arch: v7
Tag_CPU_arch_profile: Application
Tag_ARM_ISA_use: Yes
Tag_THUMB_ISA_use: Thumb-2
Tag_FP_arch: VFPv3
Tag_Advanced_SIMD_arch: NEONv1
Tag_ABI_PCS_GOT_use: GOT-indirect
Tag_ABI_PCS_wchar_t: 4
Tag_ABI_FP_denormal: Needed
Tag_ABI_FP_exceptions: Needed
Tag_ABI_FP_number_model: IEEE 754
Tag_ABI_align_needed: 8-byte
Tag_ABI_enum_size: int
Tag_ABI_HardFP_use: Deprecated
Tag_ABI_optimization_goals: Aggressive Speed
Tag_CPU_unaligned_access: v6
Tag_ABI_FP_16bit_format: IEEE 754
Tag_Virtualization_use: TrustZone
```
The precompiled `.so` downloaded from official website:
```
Attribute Section: aeabi
File Attributes
Tag_CPU_name: "ARM v7"
Tag_CPU_arch: v7
Tag_CPU_arch_profile: Application
Tag_ARM_ISA_use: Yes
Tag_THUMB_ISA_use: Thumb-2
Tag_FP_arch: VFPv3
Tag_Advanced_SIMD_arch: NEONv1
Tag_ABI_PCS_GOT_use: GOT-indirect
Tag_ABI_PCS_wchar_t: 4
Tag_ABI_FP_denormal: Needed
Tag_ABI_FP_exceptions: Needed
Tag_ABI_FP_number_model: IEEE 754
Tag_ABI_align_needed: 8-byte
Tag_ABI_enum_size: int
Tag_CPU_unaligned_access: v6
Tag_ABI_FP_16bit_format: IEEE 754
```
I’m not sure how you add the OpenCV libraries to your Android Studio project and how you’ve configured your project to begin with, but judging from the message you posted, you’re trying to link a library that is built for a different architecture. This simply means you need to make sure your OpenCV library and Android project are built for the same arch. That’s where I’d look for an answer. Hope this helps.
Finally i could build it. Thank you Amin.
How to build with another architecture like arm64-v8a, x86, etc ?
The default architecture is armeabi-v7a and could not select another one in CMake Android_ABI.
Please help about this issue
Glad you figured it out.
Regarding your question, you have to set the ANDROID_ABI accordingly.
If you check android.toolchain.cmake, you’ll notice the following:
# ANDROID_ABI=armeabi-v7a - specifies the target Application Binary
# Interface (ABI). This option nearly matches to the APP_ABI variable
# used by ndk-build tool from Android NDK.
#
# Possible targets are:
# "armeabi" - ARMv5TE based CPU with software floating point operations
# "armeabi-v7a" - ARMv7 based devices with hardware FPU instructions
# this ABI target is used by default
# "armeabi-v7a-hard with NEON" - ARMv7 based devices with hardware FPU instructions and hardfp
# "armeabi-v7a with NEON" - same as armeabi-v7a, but
# sets NEON as floating-point unit
# "armeabi-v7a with VFPV3" - same as armeabi-v7a, but
# sets VFPV3 as floating-point unit (has 32 registers instead of 16)
# "armeabi-v6 with VFP" - tuned for ARMv6 processors having VFP
# "x86" - IA-32 instruction set
# "mips" - MIPS32 instruction set
and,
# 64-bit ABIs for NDK r10 and newer:
# "arm64-v8a" - ARMv8 AArch64 instruction set
# "x86_64" - Intel64 instruction set (r1)
# "mips64" - MIPS64 instruction set (r6)
Hope it helps.
Hi. After changing ANDROID_ABI to x86 and running mingw32-make.exe I’m facing an error in command line at 42% progress:
Scanning dependencies of target IlmImf
[ 42%] Building CXX object 3rdparty/openexr/CMakeFiles/IlmImf.dir/Half/half.cpp.o
[ 42%] Building CXX object 3rdparty/openexr/CMakeFiles/IlmImf.dir/Iex/IexBaseExc.cpp.o
[ 42%] Building CXX object 3rdparty/openexr/CMakeFiles/IlmImf.dir/Iex/IexThrowErrnoExc.cpp.o
[ 42%] Building CXX object 3rdparty/openexr/CMakeFiles/IlmImf.dir/IlmImf/ImfAcesFile.cpp.o
In file included from G:\android-data\android-ndk-r14b\sources\cxx-stl\gnu-libstdc++\4.9\include/random:50:0,
from G:\android-data\android-ndk-r14b\sources\cxx-stl\gnu-libstdc++\4.9\include/bits/stl_algo.h:66,
from G:\android-data\android-ndk-r14b\sources\cxx-stl\gnu-libstdc++\4.9\include/algorithm:62,
from G:\opencv-master\3rdparty\openexr\IlmImf\ImfAcesFile.cpp:45:
G:\android-data\android-ndk-r14b\sources\cxx-stl\gnu-libstdc++\4.9\libs\x86\include/bits/opt_random.h:33:23: fatal error: x86intrin.h: No such file or directory
#include
^
compilation terminated.
3rdparty\openexr\CMakeFiles\IlmImf.dir\build.make:100: recipe for target '3rdparty/openexr/CMakeFiles/IlmImf.dir/IlmImf/ImfAcesFile.cpp.o' failed
mingw32-make.exe[2]: *** [3rdparty/openexr/CMakeFiles/IlmImf.dir/IlmImf/ImfAcesFile.cpp.o] Error 1
CMakeFiles\Makefile2:466: recipe for target '3rdparty/openexr/CMakeFiles/IlmImf.dir/all' failed
mingw32-make.exe[1]: *** [3rdparty/openexr/CMakeFiles/IlmImf.dir/all] Error 2
Makefile:161: recipe for target 'all' failed
mingw32-make.exe: *** [all] Error 2
i tested r14b and r16b ndk but not works
What’s the OpenCV version you’re trying to build?
Make sure you set ANDROID_NATIVE_API_LEVEL as described in the tutorial.
I use last ver of OpenCV and ANDROID_NATIVE_API_LEVEL is 27 as descibed.
cmake -LA :
CMake Warning:
No source or binary directory provided. Both will be assumed to be the
same as the current working directory, but note that this warning will
become a fatal error in future CMake releases.
CMake Error: The source directory "G:/ccc" does not appear to contain CMakeLists.txt.
Specify --help for usage, or press the help button on the CMake GUI.
-- Cache values
...
any solution?
What does “last ver” even mean? The version mentioned in this post is 4.0.1 (NOT TO BE CONFUSED WITH 4.1.0 WHICH IS THE “CURRENT” VERSION).
You need to figure out the right NDK version and other NDK related parameters based on the OpenCV version you are using.
Here is the folder in OpenCV source codes that will help you:
https://github.com/opencv/opencv/tree/master/platforms/android
Alternatively, just try different NDK versions until you get the right one.
Hi. When i change android_abi to x86 this error occurred :
[ 45%] Building CXX object 3rdparty/openexr/CMakeFiles/IlmImf.dir/IlmImf/ImfAcesFile.cpp.o
In file included from G:\android-data\android-ndk-r16b\sources\cxx-stl\gnu-libstdc++\4.9\include/random:50:0,
from G:\android-data\android-ndk-r16b\sources\cxx-stl\gnu-libstdc++\4.9\include/bits/stl_algo.h:66,
from G:\android-data\android-ndk-r16b\sources\cxx-stl\gnu-libstdc++\4.9\include/algorithm:62,
from G:\opencv-4.0.1\3rdparty\openexr\IlmImf\ImfAcesFile.cpp:45:
G:\android-data\android-ndk-r16b\sources\cxx-stl\gnu-libstdc++\4.9\libs\x86\include/bits/opt_random.h:33:23: fatal error: x86intrin.h: No such file or directory
#include
^
compilation terminated.
3rdparty\openexr\CMakeFiles\IlmImf.dir\build.make:100: recipe for target '3rdparty/openexr/CMakeFiles/IlmImf.dir/IlmImf/ImfAcesFile.cpp.o' failed
Sorry if I can’t help you more. Read my previous answer. Hope it helps.
I test all of another ndks but error still occurs.
Does Visual Studio or another Microsoft softwares should be installed?
Does you have checked to build another architecture yourself ?
No you don’t need anything else in particular, besides the requirements mentioned in the post.
Not sure how my answer to your second question will be of help to you.
I’d suggest to raise this as an issue with OpenCV, someone might provide you with a better answer there:
https://github.com/opencv/opencv/issues
I have this issue when run mingw32-make.exe in cmd:
–LINK–REMOVED–
please help me
Please just share the error message you receive instead of images.
Hi! Thanks for you tutorial! I have this error in before: mingw32-make:
C:\opencv_project>mingw32-make.exe
Scanning dependencies of target libcpufeatures
[ 1%] Building C object 3rdparty/cpufeatures/CMakeFiles/libcpufeatures.dir/cpu-
features.c.o
In file included from C:\opencv-4.0.1\3rdparty\cpufeatures\cpu-features.c:64:0:
C:\opencv-4.0.1\3rdparty\cpufeatures\cpu-features.h:31:23: fatal error: sys/cdef
s.h: No such file or directory
#include
^
compilation terminated.
mingw32-make.exe[2]: *** [3rdparty\cpufeatures\CMakeFiles\libcpufeatures.dir\bui
ld.make:62: 3rdparty/cpufeatures/CMakeFiles/libcpufeatures.dir/cpu-features.c.o]
Error 1
mingw32-make.exe[1]: *** [CMakeFiles\Makefile2:255: 3rdparty/cpufeatures/CMakeFi
les/libcpufeatures.dir/all] Error 2
mingw32-make.exe: *** [Makefile:162: all] Error 2
C:\opencv_project>mingw32-make
Scanning dependencies of target libcpufeatures
[ 1%] Building C object 3rdparty/cpufeatures/CMakeFiles/libcpufeatures.dir/cpu-
features.c.o
In file included from C:\opencv-4.0.1\3rdparty\cpufeatures\cpu-features.c:64:0:
C:\opencv-4.0.1\3rdparty\cpufeatures\cpu-features.h:31:23: fatal error: sys/cdef
s.h: No such file or directory
#include
^
compilation terminated.
mingw32-make[2]: *** [3rdparty\cpufeatures\CMakeFiles\libcpufeatures.dir\build.m
ake:62: 3rdparty/cpufeatures/CMakeFiles/libcpufeatures.dir/cpu-features.c.o] Err
or 1
mingw32-make[1]: *** [CMakeFiles\Makefile2:255: 3rdparty/cpufeatures/CMakeFiles/
libcpufeatures.dir/all] Error 2
mingw32-make: *** [Makefile:162: all] Error 2
C:\opencv_project>
Please make sure you have all the prerequisites and follow the instructions without missing any step. You seem to be missing something but I can’t point it out exactly with the information you have provided. If this continues to happen you can share all the steps that you have completed successfully.