tl; dr:这个问题是为了解释为什么std::stringstream
“失败”,以及它为什么会失败的方式(通过简单地无所事事),当链接到重建的c ++ _共享库。
一个最小的例子:
std::stringstream ss;
ss << "Hello World";
__android_log_print(ANDROID_LOG_INFO,
"APP",
"Length: %i", ss.str().size());
使用
编译项目时APP_STL := c++_shared
LIBCXX_FORCE_REBUILD := true
输出为Length: 0
。使用APP_STL := c++_static
或LIBCXX_FORCE_REBUILD := false
时,stringstream
按预期工作,Length: 11
作为输出。
我正在使用STL的许多部分,到目前为止我看到的唯一明显区别是这个无声的NOP
stringstream
。我还通过修改libgl2jni
NDK示例测试了这一点,将Application.mk文件添加为:
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
我已经测试了APP_OPTIM
作为发布/调试的各种排列,APP_STL
作为c ++ _ shared / c ++ _ static,LIBCXX_FORCE_REBUILD
作为true / false,在a上Nexus-4,armeabi
和armeabi-v7a
作为目标ABI
。这是结果:
|-------------+-----------+----------------------+---------+------------------|
| 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引用'__atomic_fetch_add_4'
PS:确保在这些测试之间进行ndk-build clean
。
问题:
任何人都可以了解std::stringstream
在这些情况下失败的原因,以及为什么只通过对流向它的任何数据执行NOP而失败?
由于
答案 0 :(得分:22)
我无法回答为什么NOP在一些排列中发生的原因。但我确实设法找出了构建失败的原因。
我的情况比你糟糕。我遇到了与使用c ++ _ static和LIBCXX_FORCE_REBUILD(false)的默认值相关的构建失败,并且不知道为什么。
感谢您分享您对链接STL的各种排列的研究 - 我能够直接跳到显着的文档来修复构建错误。
如果#include,你可能需要libatomic。添加&#34; LOCAL_LDLIBS + = -latomic&#34;对于ndk-build
为了能够使用libatomic,您需要将NDK_TOOLCHAIN_VERSION设置为4.8
答案 1 :(得分:2)
请试试这个:
LOCAL_LDFLAGS += -Wl,--gc-sections
似乎代码片段并没有真正调用atomic_fetch_add()。使用--gc-sections LD选项,链接器将从最终的可执行文件或共享库中消除未使用的代码和数据。因此可能会删除atomic_fetch_add()的依赖关系。
&#34; - gc-sections&#34;的描述: https://gcc.gnu.org/onlinedocs/gnat_ugn/Compilation-options.html
其他一些信息: https://code.google.com/p/android/issues/detail?id=68779