I am building an application on Android using NDK and V8. I would prefer to use C++11 and GNU STL for features such as shared_ptr; however, the V8 build system seems to be hardcoded to use stlport_static as its STL variant.
Even when patching the build system to generate a fully self-contained library, V8's build does not statically link STLport into its .a files (which is to be expected), and thus I get hundreds of linker errors from unresolved symbols in libv8_base.a et al. I also do not see any way to indicate to ndk-build that it should link in stlport_static when I am using a different STL variant.
Is there a reasonable pattern to linking in stlport_static while using gnustl_static, or, better yet, is there a way of building Android V8 against gnustl_static instead?
You have a problem. Well, mixing different STLs in separate .so's is possible, with extra care; but using two STLs inside one .so is simply impossible.
You either need to implement your own shared_ptr (no big deal), but then you will face the same issue for every other feature that exists in gnustl and not in stlport.
Or you need to port V8 to gnustl (and I am afraid that the MIT license does not allow this).
Related
I'm compiling a 3rd-party Java library for Android that uses JNI. I read the relevant pages on adding C++ support on developer.android but I'm still confused about a couple of issues regarding C++ STL runtime that I was hoping I could clear up here:
1- My library has no control over the app it will be embedded in, so I don't know if there will be other libraries that might use a static/shared STLs. If I use a static C++ runtime with ANDROID_STL=c++_static, is it safe, or should I have to worry about another library that could be using something like gnustl_static which might conflict with mine?
2- If I use a shared C++ runtime with ANDROID_STL=c++_shared, is it a guarantee that a specific element in the STL will use the libc++ runtime or could it be possible to use gnustl if it doesn't exist? For example, If I was using std::string with a shared c++ runtime (c++_shared) in an app that has another library of gnustl_static, will my std::string implementation be taken from libc++ or gnustl?
Ideally, I'd like to have a very stripped down version of a static c++ runtime with (c++_static) that only includes std::vector, std::string and std::map. I was actually planning to use something like -ffunction-sections as described here and #768.
Please advise and thank you.
Environment Details
Pkg.Desc = Android NDK
Pkg.Revision = r15c
Android Studio = 3.1.2
system: cmake Host OS: Arch Linux ($ uname -r % 4.18.5-arch1-1-ARCH)
Compiler: Clang++
STL: c++_static/c++_shared
Your concern is a very real one. But if handled properly, you can find a robust way out.
The warnings about using single C++ runtime across all libraries in the app (and the whole idea to define C++ support in NDK as APP_STL vs. most other flags such as LOCAL_CFLAGS or LOCAL_SHARED_LIBRARIES, are relevant for the native libraries that are connected. JNI libraries that never communicate directly (except through their corresponding Java layers) can use different C++ runtimes. Another point is that normal build will only package one C++ runtime shared lib into the APK. Note that versioning is also a potential hazard: if a developer who adds your library uses a different NDK release, there might be collisions or unexpected side effects when his version of STL runtime works with your code.
Therefore, to achieve maximum flexibility, your library should use a static C++ runtime. This may effect the size of the binary, but if, as you say, you use only a limited subset of STL, this extra will be rather small.
The bottom line, you will have minimum to worry about if build your shared library with libc++_static.
We have an Android application with several native libraries. Currently, most of them use stlport_shared, but we are interested in upgrading to c++_shared (the LLVM libc++ runtime). If we were to upgrade some of them, but not others, we would have to load both stlport and llvm.
I imagined that loading two implementations of the STL might cause issues, but in practice the app seems to run correctly. Is this undefined behavior, or is it allowable to load more than one STL implementation?
I've read over https://developer.android.com/ndk/guides/cpp-support.html and some of the documentation supplied with the NDK, but can't seem to find a definitive answer. Thank you for your help!
It's best to avoid this if at all possible.
If an STL type (like a std::string, for example) is accessed by both an stlport_shared binary and a c++_static binary, as the two implementations of std::string are not compatible this will not work.
You also are vulnerable to the issues described by https://stackoverflow.com/a/25856207/632035
I working on android project and I need to access the wstring_convert class in c++11 in gcc but the problem is gcc does not have this in its standard library, so am thinking of using clang std library in gcc compiler of this possible, or if there is any other way to use wstring_convert from external library like stlport but stlport development latest update is in 2008 !
Any help is appreciated.
You can choose
NDK_TOOLCHAIN_VERSION := clang
in your Application.mk
The standard C++ library from the LLVM project is:
http://libcxx.llvm.org/
It is a standalone, separate project from clang, but I never heard of someone using it with GCC. There are parts of the standard library which rely on compiler-specific internals (e.g., some type traits), so I am not sure this is going to work.
edit
From the front page:
libc++ is known to work on the following platforms, using g++-4.2 and clang (lack of C++11 language support disables some functionality). Note that functionality provided by is only functional with clang.
So it looks like it might actually work with at least some versions of GCC.
I am developing a library for Android which has both Java and Native components. The Native library depends on the GNU STL. I was linking against gnustl_static, but have ran into a few strange problems that were resolved by linking gnustl_shared. (for example the question Filesystem and locale). For the time being, I have settled on gnustl_shared.
Here's where the question is -- the consumer of my library is expected to link against the Native .so to add code of their own. I understand from reading that all the C-runtimes must match.
Demanding my clients use gnustl_shared seems like it might not work (as far as diplomacy and ease of integration goes)
If I build with gnustl_shared, the JAR file generated contains libgnustl_shared.so, which causes a problem building an APK which also relies on this library. -- I suppose I can just not include it in the JAR file?
If I build against gnustl_static do I avoid all these problems?
If my API contains refernces to STL objects (mostly std::string and std::vector), will I face problems if my clients do not use GNU STL?
thanks
I'm using the newest Android NDK r6b to build my shared object. This library does not use any kind of STL at all, but resulting .so includes many STL stuff like std::bad_alloc_what(void) and many more, which increases size of binary greatly. Also release builds include this garbage. APP_STL not defined anywhere, also the NDK r5b produces small binary with used functions only. Is it a bug of r6b? How can I build with r6b without STL stuff?
It seems that there is a bug in NDK r6b and it always builds libraries with exceptions support, even if -fno-exceptions is explicitly specified.
See this question for details: Android NDK produce unreasonable big binaries, how to optimize .so size?
If you are using, say, new then you are implicitly using the standard library for the std::bad_alloc exception. Unless you call the no-throw version of new, which would instead use std::nothrow. If you don't use the standard library, then it won't get linked. Just make sure you don't, if that's what you want, or perhaps just move to C?