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