#android #c #android-ndk #cmake #clang
#Android #c #android-ndk #cmake #лязг
Вопрос:
Возможно ли связать версии библиотек platforms android-XX arch-arm usr lib * .a при использовании системы сборки NDK Cmake с Android Studio? Я использую набор инструментов LLVM и Android NDK 13.
Я пробовал вносить изменения в образец приложения, изменяя файл: https://github.com/googlesamples/android-ndk/blob/master-cmake/hello-jni/app/src/main/cpp/CMakeLists.txt
Со следующей модификацией (добавление libm.a):
target_link_libraries(hello-jni libm.a android log)
Сборка прошла успешно, но readelf -d показывает, что libm.so все еще связан:
0x00000001 (NEEDED) Shared library: [libandroid.so]
0x00000001 (NEEDED) Shared library: [liblog.so]
0x00000001 (NEEDED) Shared library: [libm.so]
0x00000001 (NEEDED) Shared library: [libdl.so]
0x00000001 (NEEDED) Shared library: [libc.so]
При добавлении также libc.a становится хуже, сборка завершается неудачно:
Error:error: relocation overflow in R_ARM_THM_JUMP11
Error:error: linker command failed with exit code 1 (use -v to see invocation)
Кстати, иногда я вижу только последнюю ошибку без каких-либо объяснений (например, при неправильном написании имени библиотеки). Должен ли я как-то установить флаг -v, чтобы увидеть более подробную информацию? Как это сделать?
Комментарии:
1. К вашему сведению, статическое связывание libc с вашим приложением будет болезненным. Зигота будет иметь собственную дублирующую копию одних и тех же глобальных данных, и они будут конфликтовать.
2. @DanAlbert Я вижу. Просто для ясности, вы говорите о некоторых глобальных данных, используемых внутри libc.a, которые используются косвенно и совместно используются пользователями библиотеки?
3. Может быть, можно как-то связать только необходимые части из статической библиотеки и избежать проблем с глобальными данными? Я думаю, что при статической компоновке компоновщик импортирует только необходимые вещи.
4. «Необходимые вещи» с точки зрения среды выполнения C включают глобальные данные. У нас есть планы по созданию чего-то подобного в NDK (чтобы вы могли получить доступ к новым функциям libc на старых устройствах), но это еще не готово. Возможно, использование статического libc в приложении менее катастрофично, чем я ожидаю. Я, честно говоря, не пробовал, но у подобных вещей, которые я пробовал, была эта проблема.
Ответ №1:
Если вы просто хотите, чтобы это было скомпилировано, я бы попытался использовать arm-linux-androideabi-gcc вместо clang. Я понимаю, что gcc обесценился. Но я не могу, если ваша цель — скомпилировать или понять проблему. Судя по комментарию Дэна, я предполагаю, что он не верит, что какой-либо из флагов, которые он прокомментировал в aosp, поможет (см. Ссылку Ниже)
https://android.googlesource.com/platform/build/ /master/core/clang/config.mk
Черт возьми, я всегда использую статические библиотеки из сборок aosp / bionic, которые я делаю, потому что я работаю над множеством вещей, которые их требуют. я полагаю, что в символах, включенных в bionics libc, между версиями sdk слишком много несоответствий, и для статического связывания требуется использовать libc.a по большей части. Если вы собираетесь использовать ndk-версию статического libc, я бы предложил использовать платформу 21 вместо 24.
Я полагаю, что, поскольку Android настолько фрагментирован, и все устройства используют разные libc.so , libdl.so , и т.д., что это не может вызвать слишком много проблем.
РЕДАКТИРОВАТЬ: неправильно истолковал вопрос.
Комментарии:
1. Оказывается, я установил minSdkVersion равным 15 в build.gradle(app), поэтому компоновщик попытался связать libc.a из этой папки. При переключении minSdkVersion на 21 использовалась правильная версия libc.a, и все было успешно скомпилировано, хотя readelf все еще показывает libc.so но я думаю, это потому, что этого требуют другие части родной библиотеки. Но загрузка общей библиотеки завершается сбоем как с помощью gcc, так и с clang — только при использовании статического libc.a:
SIGSEGV (signal SIGSEGV: address access protected (fault address: 0x206e7777))
я думаю, это потому, что статическая версия libc конфликтует с общей, как упоминал Дэн.2. Если вы создаете общую библиотеку, вы не можете связать ее с libc.a, вы должны использовать libc.so (ну, ты можешь, но это не очень хорошая идея, как сказал Дэн), извини, я думал, ты создаешь исполняемый файл. Насколько я понимаю, почему вы хотите использовать статические библиотеки при создании общей библиотеки? Честно говоря, вы могли бы, вероятно, включить статические версии всех этих необходимых библиотек, кроме libc. Но опять же, я не уверен в причинах желания связать их статически, если ваша цель — создать общую библиотеку.
3. Конечной целью также было преобразовать *.so в *.a . Я хотел бы иметь статическое связывание, чтобы избежать простого переопределения функций C (например, memcpy и т. Д.), Когда кто-то пытается злоупотреблять моей библиотекой. Поскольку эти функции работают с данными, которые я хотел бы скрыть. В чем разница между связыванием статической библиотеки с исполняемой или разделяемой библиотекой в этом контексте?