tl;dr: The question is for an explanation for why std::stringstream "fails", and why it fails in the way it does (by simply doing nothing), when linking to a rebuilt c++_shared library.
A minimal example:
std::stringstream ss; ss << "Hello World"; __android_log_print(ANDROID_LOG_INFO, "APP", "Length: %i", ss.str().size()); When compiling the project with
APP_STL := c++_shared LIBCXX_FORCE_REBUILD := true The output is Length: 0. When using APP_STL := c++_static or LIBCXX_FORCE_REBUILD := false, the stringstream works as expected, with Length: 11 as output.
I'm using many parts of the STL, and the only noticeable difference I've seen so far is this silent NOP stringstream. I've also tested this by modifying the libgl2jni NDK sample, adding the Application.mk file as:
NDK_TOOLCHAIN_VERSION := 4.8 APP_OPTIM := release APP_STL := c++_shared APP_ABI := armeabi-v7a #armeabi-v7a x86 APP_PLATFORM := android-19 LIBCXX_FORCE_REBUILD := true I've tested the various permutations of APP_OPTIM as release/debug, APP_STL as c++_shared/c++_static, and LIBCXX_FORCE_REBUILD as true/false, on a Nexus-4, with both armeabi and armeabi-v7a as target ABI. This is the result:
|-------------+-----------+----------------------+---------+------------------| | ABI | stl c++_? | LIBCXX_FORCE_REBUILD | optim | Result | |-------------+-----------+----------------------+---------+------------------| | armeabi | static | true | release | OK | | | static | true | debug | OK | | | static | false | release | BUILD FAILED [1] | | | static | false | debug | BUILD FAILED [1] | | | shared | true | release | NOP | | | shared | true | debug | NOP | | | shared | false | release | OK | | | shared | false | debug | OK | |-------------+-----------+----------------------+---------+------------------| | armeabi-v7a | static | true | release | OK | | | static | true | debug | OK | | | static | false | release | OK | | | static | false | debug | OK | | | shared | true | release | NOP | | | shared | true | debug | NOP | | | shared | false | release | OK | | | shared | false | debug | OK | |-------------+-----------+----------------------+---------+------------------| [1] /opt/android-ndk-r9d/sources/cxx-stl/llvm-libc++/libs/armeabi/libc++static.a(ios.o):/tmp/ndk-andrewhsieh/tmp/build-21097/build-libc++/ndk/sources/cxx-stl/llvm-libc++/libcxx/src/ios.cpp:function std::_1::ios_base::xalloc(): error: undefined reference to '__atomic_fetch_add_4'
PS: Make sure to do a ndk-build clean in between these tests.
The question: Could anyone give some insight into why std::stringstream fails given these circumstances, and why it fails by just doing a NOP on any data that is streamed to it?
Thanks
I can't answer why the NOP is occurring in some permutations. But I did manage to find out about the build failures.
I was in a worse situation than you. I was experiencing the build failures relating to the combination of using c++_static and the default value for LIBCXX_FORCE_REBUILD (false) and had no idea why.
Thanks to you for sharing your research into the various permutations of linking STL - I was able to jump straight to the salient documentation to fix the build error.
It's likely that you need libatomic if you #include . Add "LOCAL_LDLIBS += -latomic" for ndk-build
To be able to use libatomic you need to set your NDK_TOOLCHAIN_VERSION to 4.8
Please try this:
LOCAL_LDFLAGS += -Wl,--gc-sections It seems that the code snippet doesn't really called atomic_fetch_add(). With --gc-sections LD option, the linker will eliminate the unused code and data from the final executable or shared library. So that the dependency of atomic_fetch_add() is likely to be removed.
Description of "--gc-sections": https://gcc.gnu.org/onlinedocs/gnat_ugn/Compilation-options.html
Some other infomation: https://code.google.com/p/android/issues/detail?id=68779
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With