Подтвердить что ты не робот

Android NDK STL С++ _ shared w/LIBCXX_FORCE_REBUILD приводит к std:: stringstream NOP

tl; dr: Вопрос заключается в объяснении того, почему std::stringstream "не удается", и почему он терпит неудачу в том, как он это делает (просто ничего не делая), когда ссылается на перестроенный С++ _ shared library.

Минимальный пример:

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 как release/debug, APP_STL как С++ _ shared/С++ _ static и LIBCXX_FORCE_REBUILD как true/false, на 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-libС++/ndk/sources/cxx-stl/llvm-libС++/libcxx/src/ios.cpp: function std:: _ 1:: ios_base:: xalloc(): error: undefined ссылка на ' __atomic_fetch_add_4

PS: Обязательно выполните ndk-build clean между этими тестами.

Вопрос: Может ли кто-нибудь дать представление о том, почему std::stringstream не справляется с этими обстоятельствами и почему он терпит неудачу, просто делая NOP для любых передаваемых на него данных?

Спасибо

4b9b3361

Ответ 1

Я не могу ответить, почему NOP встречается в некоторых перестановках. Но мне удалось узнать о сбоях сборки.

Я был в худшем положении, чем вы. Я испытывал сбои сборки, связанные с комбинацией использования С++ _ static и значением по умолчанию для LIBCXX_FORCE_REBUILD (false) и понятия не имел, почему.

Спасибо вам за то, что вы делитесь своими исследованиями с различными перестановками связывания STL - я смог перейти прямо к важной документации, чтобы исправить ошибку сборки.

Вероятно, вам нужно libatomic, если вы #include. Добавьте "LOCAL_LDLIBS + = -latomic" для ndk-build

Чтобы использовать libatomic, вам нужно установить NDK_TOOLCHAIN_VERSION в 4.8

Ответ 2

Пожалуйста, попробуйте следующее:

LOCAL_LDFLAGS += -Wl,--gc-sections

Кажется, что фрагмент кода на самом деле не называется atomic_fetch_add(). С опцией LDG -gc-секций компоновщик удаляет неиспользуемый код и данные из окончательной исполняемой или разделяемой библиотеки. Так что зависимость atom_fetch_add() скорее всего будет удалена.

Описание "--gc-sections": https://gcc.gnu.org/onlinedocs/gnat_ugn/Compilation-options.html

Некоторые другие данные: https://code.google.com/p/android/issues/detail?id=68779