I have to compile a library (library BPG from Bellard.org) to create a .so or a dll that I can use with android/iOS.
I'm working with Visual Studio. With some researches, I found the project "Visual C++ -> Cross Platform -> Shared Library (Android, iOS)". But I am totally lost and can't do anything.
The downloaded library is organised with some folders but Visual don't allow to make tree, all files are sorted by filters (one for header and one for sources). So I can't build, I have more than 300 errors, "can't open source file", "undefined variable"...
Secondly, the README file from project says :
The following packages need to be installed: mingw64-gcc mingw64-libpng mingw64-libjpeg-turbo mingw64-SDL mingw64-SDL_image yasm
I found installed for mingw 32 bits but no 64 bits so I don't know if build can perform. I don't know how to find the libraries.
So my question is, what is the best way to compile a C/C++ library for android/iOS ? And where can I find a tutorial for beginners ?
Thank you
I have worked as cross compiling engineer for several years. The most suitable IDE for you I think, is the CLion with CMake inside.
CMake is a tool which can cross-compile the C/C++ library into ios\android\linux\etc.. using only one config file: "CMakeList.txt".
The main task of CMake is to translate CMakeList.txt to Makefile on every platform and provide you the .a and .so files.
CLion is very powerful IDE in code editing and debugging.
Furthermore, Android needs JNI (or JNA if performance is not concerned) to wrap your c++ interfaces to java classes. Here I would recommend SWIG. SWIG is a tool to wrap C++ interfaces to other languages, that means, not only java on android you can support , other days your lib can also support python\tcl\Go\etc.
Which os are u using to build the lib? macOS or win ?
For iOS : .a file
For Android: .so file
First you should check the README file
Edit the Makefile to change the compile options (the default
compile options should be OK). Type 'make' to compile and 'make
install' to install the compiled binaries.
Use 'make -j N' where N is the number of CPU cores to compile faster.
The following packages must be installed: SDL-devel
SDL_image-devel yasm. It is recommended to use yasm version >= 1.3.0
to have a faster compilation.
Only a 64 bit target is supported because x265 needs it for bit
depths > 8.
check this to install SDL packages
https://wiki.libsdl.org/Installation
Related
I tried to compile a .so library using Visual Studio 2019 along with OpenCV Android in order to use this library in Unity.
There are some answers on how to configure Visual Studio to use OpenCV Android (here or here) but none of these work for me. Below you can see my configurations.
Visual Studio 2019 (running on Windows 10)
android-ndk-r21e // also tried with android-ndk-r15c android-ndk-r16b and android-ndk-r17c
OpenCV Android 4.5.2 // also tried with OpenCV Android 4.0.0, 4.0.1 and 4.1.0
My settings in Visual Studio 2019 look as follows:
Configuration Properties
- General
Platform Toolset Clang 5.0 (also tried Clang 3.8 or GCC 4.9)
Configuration Type Dynamic Library (.so)
Target API Level Nougat 7.0 (android-24) (also tried different versions)
Use STL LLVM libc++ static library (c++_static) (also tried "GNU STL static library (gnustl_static)")
C/C++
- General
Additional Include Directories "Path to OpenCV_4_5_2_Android\sdk\native\jni\include"
Code Generation Enable C++ Exceptions "Yes(-fexceptions)"
Language C++17(-std=c++1z)
Precompiled Headers Not using Precompiled Headers
Linker
- General
Additional Library Directories Path to OpenCV_4_5_2_Android\sdk\native\libs\armeabi-v7a
- Input
Additional Dependencies Path to OpenCV_4_5_2_Android\sdk\native\libs\armeabi-v7a\libopencv_java4.so
My Source.cpp I try to compile is just a single function for testing purposes
#include <opencv2/core.hpp>
extern "C" float test(float a, float b)
{float c = a * b; return c;}
Which gives me the following errors:
E0035 #error directive: This constructor has not been ported to this platform
E0020 identifier "__fp16" is undefined
use of undeclared identifier 'ANDROID_LOG_INFO'
The ANDROID_LOG_INFO error can be fixed when I add #include "android/log.h" at the top of the file that throws this error. But the other two errors still remain.
I had the exact same issue as you (though I used c++ 11) with the exact same setup, and struggled for days. I believe the errors you're seeing (like me) are from arm_neon.h. Very oddly, I was able to just build (not run) the .so successfully, even with those errors (I say "errors" because if you look at arm_neon.h, others pop up), so try it. Maybe it's some kind of IntelliJ/Intellisense mistake more than anything else where it's catching false negatives from some other toolchain setup.
At the same time, I'm not 100% sure I was always able to build with that issue, so try these steps as well if you can't:
use OpenCV 4.0.1 with Android NDK 16rb. The NDK matters when it comes to OpenCV builds, and this is the only supposed match that I know of.
follow this tutorial from scratch: https://amin-ahmadi.com/2019/06/03/how-to-use-opencv-in-unity-for-android/
if the downloaded OpenCV android SDK is still giving trouble, build OpenCV from the source using his other tutorial here: https://amin-ahmadi.com/2019/02/03/how-to-build-opencv-4-x-for-native-android-development/
and then repeat step 2.
MAJOR EDIT:
OpenCV 4.5.2 needs to be treated differently because it no longer uses toolchains with gnu c++.
-When you build OpenCV from CMake, build with Android NDK 21e, and do not use the toolchain in OpenCV 4.5.2. Use the one inside the Android NDK's build folder (android-ndk-r21e\build\cmake).
-When you build your .so from Visual Studio 2019, do not use the GNU STL, use the LLVM. GNU c++ is no longer part of Android NDKs, and you need to cut it out of the process entirely.
-In the Linker Input, put the names of your library files (or file, if it's just the world one) in the Library Dependencies field, not the Additional Dependencies field.
-Everything else is the same as in those common tutorials.
I have some C++ code (interacts with micro controllers) written already by someone else. I learnt android & NDK and comfortable writing small sample programs. Now I need to integrate both.
So, How should I start proceeding on the integration part? How does the NDK actually works? Assuming I have 3 parts now A - C++ code, B - NDK native interface code, C - Android Activity/Class .
1) Should I compile A (g++ linaro) and then place the object file in Android project to be called by C through B?
(or)
2) Should I compile the A & B together using g++ (linaro) and then copy the .so file into the Android Eclipse project? (Not sure how complex it will be to mimic NDK-build command in normal eclipse).
(or)
3) Copy A into Android Eclipse project and generate java.h file, then generate .so file using the both A & B. (In this method I need to find the right place to put the whole CPP project files in the Android/NDK eclipse project).
PS: I tried to find examples that does this, but only seem to find the simple basic examples, which I am pretty comfortable creating already. I need help in the integration part, please post me tutorial if you know (Android/NDK/Eclipse/already_existing_C++_code).
You should compile A using the Android toolchain. Note that Android supports not only ARM (a.k.a. armeabi) but also armv7a, x86, mips, and recently - armeabi-v7a-hard. Soon, x86-64 will be released.
You can compile A with Android standalone toolchain, no need to adopt the NDK build system.
You can compile B as part of A, or separately. In the latter case, simply load A before B in your Java static constructor:
{
loadLibrary("A");
loadLibrary("B");
}
because libB.so will have dependencies on libA.so.
You can pack both libA.so and libB.so in the APK (in folders libs/armeabi, libs/x86, etc.)
First of all, I recommend you to read Android NDK documents. Android.mk is not hard to write in order to compile C++ code into shared library for JNI using NDK toolchain. The most difficult part might be that Android libc (bionic) is not the same as ordinary Linux libc.
So, try to compile A - C++ code using NDK toolchain first. If you failed it, you should port it to Android libc, or you should compile it and link statically it using linaro toolchain. Take a look at the documents to link static elf library using NDK toolchain. But the binary wouldn't work on Linux because Android Linux kernel is not the same as linaro.
Anyway if you got to compile a shared library, easy to integrate it to Android project. just put the shared library to libs/[arch], like libs/armeabi-v7a/libfoo.so.
I've been working on an Android project which has several native C++ libraries. Compiling and debugging using Eclipse with ADT plugin works well. Obviously Android NDK uses arm-linux-gnueabi-gcc of some version to compile the native libraries.
Since I've been using NEON intrinsics heavily, I would like to try to compile the native libraries with ARM's official compiler armcc. I read everywhere that armcc is supposed to give better optimized code when using intrinsics. So I downloaded the trial version of DS-5 from ARM website, just to try and see whether there's really any speed difference.
The DS-5 seems to be just a modified version of Eclipse that uses the ARMCC toolchain, so I installed the ADT plugin. But when I compile using DS-5, it seems that the code is still generated using gcc rather than armcc.
Do you have any idea how to force DS-5 or Eclipse to build the Android native code using armcc? Or is it possible (and how) to build the static NDK libraries from command line and then replace the libraries in my project, so they get deployed to the testing phone?
ARM DS-5 Community Edition doesn't include ARM compiler (armcc).
If you could get hold of armcc best would be to separate your processing heavy algorithms to individual compilation units (separate C files), build them with armcc as you would do for any compilation unit. When you get the object files, convert them into an archive then use that in Android.mk as LOCAL_STATIC_LIBRARIES += <your_archive>.
You can't use armcc plainly to build Android compatible libraries mostly because of Bionic dependencies, I think.
You can use armcc to build Android compatible static libraries even though Android has a different C library (bionic). The key is the --library_interface flag for armcc. According to the documentation:
Use an option of the form --library_interface=aeabi_* when linking with an ABI-compliant C library. Options of the form --library_interface=aeabi_* ensure that the compiler does not generate calls to any optimized functions provided by the ARM C library.
In addition, there are a few more flags to ensure compatibility with the Android EABI resulting in the following command for an Android armeabi-v7a target:
armcc --library_interface=aeabi_clib --wchar32 --enum_is_int --no_hide_all --cpu=7-A --fpu=softvfp+vfpv3 -c -o libfunc.o libfunc.c
You can then use armar --create libfunc.a libfunc.o to create a static library that can be linked with the Android NDK as LOCAL_STATIC_LIBRARIES.
I have successfully tested this with Android NDK r10d on Android KitKat 4.4.2.
I'm using the Android NDK and Cmake to generate shared libraries of my project.
I'm porting an existing project from Ubuntu to Android, and right now I need to port some executables files. I compile successfully all the executable file sexecpt one which needs the Threads library.
In CMakeList.txt, there is FIND_PACKAGE(Threads) which finds the library while compiling for Ubuntu, but not for Android.
I followed this cmake and libpthread but with no success.
I think I should write the FindThread.cmake file but I'm pretty new to CMake and don't really know how to do it, especially as I don't know where is located the thread library for Android.
Any help would be appreciated.
Thank you
Under Android, there is no need for FIND_PACKAGE(Threads) because the Android libc standard library (called "bionic") already includes the relevant functions in threads.h and pthread.h. That support is not yet completely POSIX compliant and differs by API level, but will be sufficient for most cases.
So you can just skip over finding and linking to an external threads library. If your CMake file is meant for cross-platform use, it would look like this:
set(CMAKE_THREAD_PREFER_PTHREAD TRUE)
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
if(NOT CMAKE_SYSTEM_NAME STREQUAL "Android")
find_package(Threads REQUIRED)
target_link_libraries (your-target-name PRIVATE Threads::Threads)
endif()
You don't need to write your own FindThread.cmake. On a standard linux installation, it can be found within /usr/share/cmake-2.8/Modules/ .
Check where this Modules/ directory might be installed on your platform.
I have a cross-platform C library that I need to compile for Android as a *.so file. The library consist of many .c and .h files, and it use autotools as it's buid system. (./configure && make dep && make). Afaik, the library does not depend on other libraries, other than libc and OpenSSL (which should be present on Andriod).
I'm trying to find the simplest (read fastest in terms or not needing to read hundreds of pages of manuals and then apply try && fail brute-force approaches to complete the task) way of getting the library off my machine in source code form, and into the Android phones as a .so. The library will eventually be accessed from Java's native library interface. For development, I have both Windows and Debian machines on my desk.
If you're lucky and the autotooled project is set up correctly, you can cross-compile by running (this example is cross-compiling for windows using mingw, I do not know what the prefix is for Android):
./configure --host=i586-pc-mingw32
This will then try to find compilers with a prefix of i586-pc-mingw32-, so i586-pc-mingw32-gcc will likely be the first one found and used. For your Android devkit, have a look at what your compiler binary is called and guess the host value from that.
We ended up manually creating an Android NDK project with all the required files.