Android NDK STL c ++ _ shared w / LIBCXX_FORCE_REBUILD导致std :: stringstream NOP

时间:2014-04-13 10:07:03

标签: android c++ stl android-ndk

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++_staticLIBCXX_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,armeabiarmeabi-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而失败?

由于

2 个答案:

答案 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