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 для любых передаваемых на него данных?
Спасибо
Ответы
Ответ 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