I am compiling C++ library code in Android Studio 2.2. I follow the new guide, where I add all the files to my project and compile it using CMake (and CMakeLists.txt) like this. I want to use C++14 features, and stuff like atomic, stoi etc. but the building is failing with errors.
error: no type named 'condition_variable' in namespace 'std'
error: no member named 'stoi' in namespace 'std'
This is what my CMakeLists looks like (other lines set source files and other stuff):
find_library(GLES GLESv2)
include_directories(${COMMON_PATH} /usr/local/include)
set(ANDROID_STL "c++_shared")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++14 -latomic")
add_library(native-lib SHARED ${COMMON_SRC})
target_link_libraries(native-lib ${GLES})
I found this article on the android page (here), but I don't know how and if I can do this when using CMakeLists and not ndk-build. I see other question that solve it using the c++_static runtime but only with ndk-build.
This documentation would be more useful for cmake case:
arguments "-DANDROID_STL=c++_shared
Gradle also packs libc++_shared.so into APK when using c++_shared; bypassing Gradle might cause trouble for your app on early version of Android OS.
at the time of this question, Android Studio might have trouble; at the time now Android Studio 3.1.3, it should be ok
The cross-compilation process used to generate the native libraries for Android uses the c++ dependencies from the NDK libraries. The NDK provided by Google is good and it has lots of things, but the C++11 and C++14 support is not complete.
If you want to use C++14 features, you can use other NDK like CrystaX NDK for example. With CrystaX you have also C++17 support.
Related
We have a project that uses a library that is built on top of Google's Mediapipe, which is built using the Bazel build system.
The project itself is an Android Native Library, built using Gradle with CMake
externalNativeBuild {
cmake {
cppFlags "-std=c++17 -fopenmp -static-openmp -fexceptions -frtti -Wl,-s -Wno-unused-command-line-argument"
arguments "-DANDROID_STL=c++_shared", "-DOpenCV_DIR=${opencvDir}", "-DANDROID_ARM_NEON=TRUE"
}
}
So we end up with 2 (or more later, also dependent on OpenCV for example) shared object libraries - the actual SDK & the Mediapipe project.
We're seeing issues that are similar to this, which lead me to look into the runtime part of our project.
E/libc++abi: terminating with uncaught exception of type std::bad_cast: std::bad_cast
I saw this comment on that issue thread, and adding
System.loadLibrary("c++_shared");
Solved the crash.
However, this is not a practical solution as the project we're building would provide a native SDK in the form of multiple .so files and I wouldn't want to force our clients to have to explicitly load the shared runtime library before using our library.
The gradle library has "-DANDROID_STL=c++_shared" flag, so this is using the shared one, but I couldn't find any way to compile Mediapipe (with Bazel) using c++_shared. I couldn't find any reference to using shared runtime when compiling Bazel projects (except for this, which isn't exactly relevant and the solution didn't help me)
We might be able to work around this by setting -DANDROID_STL=c++_static, but this has other issues, mainly, it violates Android's guidelines for using multiple shared libraries, though it might be possible for for middleware vendors
So the question is,
Is it possible to build Mediapipe (or any other Bazel based) using c++_shared Android STL
If not, are there any other options to solve the runtime conflicts
Is it even a runtime conflict or something else?
I managed to get it working as suggested by using c++_static on all of our shared objects (SDK, Mediapipe, OpenCV and others)
I use noise suppression APIs from OpenSL lib on android and seems it is not included in older NDKs prebuilt OpenSL library. So I got errors like "undefined reference to `SL_IID_ANDROIDNOISESUPPRESSION'". I think this is r17c NDK issue because I have not such errors on r21b. But currently I can not update NDK version for my big legacy crossplatform project. So I want to disable undefined symbols checking while linking to OpenSL ES library on android. I know how to do this for entire project for example from gradle (-DANDROID_ALLOW_UNDEFINED_SYMBOLS=TRUE) but is there possibility to do this only for OpenSL library or at least for my cmake audio module (described in separate cmake file and included in main project).
I'm not very good at cmake and clang linker flags. Trying to do this second day without success(
There is how I include OpenSL on android:
target_link_libraries(my_audio
PRIVATE
android
log
atomic
OpenSLES)
I have an android project that currently uses Cmake for including all .cpp /.c code. Now I want to add the GStreamer native libraries such that I can use them in my native code.
But the gstreamer docs https://gstreamer.freedesktop.org/documentation/installing/for-android-development.html
only document using ndk-build to use gstreamer on android.
Now I don't want to totally refactor my project to use ndk-build and Android.mk because
CMake does its job and i never had problems with it
as stated here cmake is the default for android ndk https://developer.android.com/studio/projects/add-native-code
I also need to include the googlevr ndk library that uses cmake.
So I need to figure out a workaround and therefore need your help. Here are some ideas I came up with
Each module can have ether cmake or ndk-build support. Therefore,
I probably could add a new module using ndk-build and include gstreamer there (but then gstreamer is only available in this module)
Compile gstreamer for android using cmake inside android studio - but I don't see evidence that has been done before or is possible for someone without strong cmake knowledge.
Any other ideas/ improvements ? thanks
Even though you have already moved away from GStreamer but in case someone else is facing this issue please have a look at following github repository
https://github.com/henkeldi/gstreamer-android
For myself, I had to make two modifications
I modified the definition of GSTREAMER_ROOT to include ANDROID_ABI so it looks like following
#GStreamer
set(GSTREAMER_ROOT $ENV{GSTREAMER_ROOT_ANDROID}/${ANDROID_ABI})
I had to rename the folders in GStreamer pre-built binaries to be according to ANDROID_ABI. So, my Gstreamer pre-built binaries folder look like following
After the above changes, I am able to successfully build with APK with GStreamer using CMake
At some point I gave up on gstreamer and am now using ffmpeg instead.
There is a nice tutorial for compiling ffmpeg that makes including native ffmpeg inside an android project really easy:
Tutorial on Medium
Github project
I'm trying to create a C/C++ library using the latest version of Android studio (2.2.2).
How can I specify different compile options for different code files?
Some of the .cpp code in my library uses STL and requires "-std=gnu++11" in order to successfully compile.
Some of the code in my library uses .c files, which generates this error if "-std=gnu++11" is specified:
Error:invalid argument '-std=gnu++11' not allowed with 'C/ObjC'
I am currently using a build.gradle script to compile, but I'd also be open to using CMake, if someone can help me set up a CMake script to accomplish the same thing.
I saw other answers that specified cppFlags, rather than cFlags, in order to specify compile flags for only .cpp files. That NDK option appears to be missing from the latest version of Android Studio. When I try to use it, I get this error:
Could not get unknown property 'cppFlags' for object of type
com.android.build.gradle.internal.dsl.NdkOptions.
Thanks for your help!
By generating a new C++ library module from Android Studio, I was able to get a skeleton CMake setup. cppFlags works normally from CMake files, so my problem is solved!
Basically, I want to know how to use a c++ shared library in Android Studio in NDK code (inside jni part). There is quite a lot of questions about that but they all are based on changing Android.mk which is not a way to go because in AS it's generated automatically.
To use pre built librairies with Android Studio, you have to follow these steps:
Compile your C++ librarie with ndk-build (here you build librairies for Android architecture such like arm, x86, etc.).
Create a Java class and JNI wrapper for your C++ methods.
You have then to disable gradle for ndk-build and create your own Android.mk and Application.mk in the jni folder.
Import the .so library and pre build it in the Android.mk.
Invoke ndk-build manually, from the Android Studio console.
Then, include the header of your librarie and call its functions in your JNI part.
For any complement of information, I advise you the intel video that you can find here.