Android NDK STL c++_shared w/LIBCXX_FORCE_REBUILD results in std::stringstream NOP

匿名 (未验证) 提交于 2019-12-03 02:47:02

问题:

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

回答1:

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



回答2:

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



易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!