Проблема: Мне нужно перенести gnutls на Android, чтобы использовать его в общей библиотеке (скажем, в библиотеке A), которую я использую в своем приложении для Android.
Что я пробовал: Я изменил сделать файл для openconnect для создания файла статической библиотеки .a для gnutls и его зависимостей (libgmp, libnettle и libhogweed) я использовал их для создания статических библиотек в своем проекте Android и ссылался на них в общей библиотеке A. Код прекрасно собирается и устанавливается, но на Устройства M + я получаю следующую ошибку во время выполнения:
java.lang.UnsatisfiedLinkError: dlopen failed: libA.so: has text relocations
Я пытался передать -fPIC
При сборке статических библиотек (файлов .a) и при неудачном создании файла libA.so я всегда вижу записи TEXTREL в файле libA.so. Я уверен, что это связано с этими новыми статическими библиотеками, так как раньше я использовал libA без проблем.
Другая вещь, которую я попробовал: попытался собрать gnutls как общую библиотеку, сгенерированный libA.so теперь не имел перемещения текста, но все равно не мог бы загружаться во время выполнения, потому что у gnutls файлов есть версия (например, libgnutls.so.3.0), а Android не поддерживает версионные библиотеки.
Конкретный вопрос: Как я могу: 1. Создать gnutls как статическую библиотеку без перемещения текста или 2. Создать как общую библиотеку без soname?
Редактировать: я вижу то же самое вопрос спросил в списке рассылки openconnect, но не дал четкого объяснения, как «сначала исправить TEXTREL в нативном коде».
Я видел другие ответы на проблемы с перемещением текста, как это вопрос а также этот вопрос, но это не помогло, так как я использую последнюю сборку NDK и уже передаю флаг PIC
Вы не можете загрузить библиотеку, которая требует перемещения текста:
Начиная с API 23, общие объекты не должны содержать перемещения текста. То есть код должен быть загружен как есть и не должен изменяться.
(источник)
ответы:
Как я могу построить gnutls как статическую библиотеку без перемещения текста?
-fPIC
не может предотвратить перемещение всего текста. В некоторых случаях, если ваша библиотека использует inline asm
, компилятор не сможет сделать его независимым от положения (PIC
). Однако, если вы уверены, что ваша библиотека может быть независимой от позиции, проблема может быть где-то в вашей конфигурации сборки.
Если нет, вы должны запретить вашей библиотеке использовать текст Relocations. К счастью, есть отличная вики-страница, которая объясняет, как это сделать в Gentoo Wiki.
Как я могу создать его как общую библиотеку без soname?
Вы можете установить свое имя с помощью: gcc -shared -Wl,-soname,your_soname
,
Я наконец-то понял. Так как gnutls зависит от nettle и gmp, в то время как nettle также зависит от gmp, мне пришлось собирать gmp как разделяемую библиотеку, а остальное как статическую. Поскольку libgmp был единственным зданием без сонам, у меня не было проблем построить его таким образом. Итак, это мой последний Android.mk:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libgmp
LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libgmp.so
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libhogweed
LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libhogweed.a
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libnettle
LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libnettle.a
LOCAL_SHARED_LIBRARIES := libgmp
include $(PREBUILT_STATIC_LIBRARY)
include $(CLEAR_VARS)
LOCAL_MODULE := libgnutls
LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libgnutls.a
LOCAL_SHARED_LIBRARIES := libgmp
LOCAL_STATIC_LIBRARIES := libhogweed libnettle
include $(PREBUILT_STATIC_LIBRARY)