使用静态gnutls库的共享库具有文本重定位

时间:2016-08-30 16:35:14

标签: android c++ android-ndk gnutls

问题:我需要将gnutls移植到Android,以便在我的Android应用程序中使用共享库(比如库A)。

我尝试了什么:我已经为openconnect修改了make file,为gnutls及其依赖项生成.a静态库文件(libgmp,libnettle和libhogweed),我用它们在我的Android项目中构建静态库并在共享库中引用它们。代码构建和安装很好但在M +设备上我在运行时遇到以下错误:

java.lang.UnsatisfiedLinkError: dlopen failed: libA.so: has text relocations

我在构建静态库(.a文件)时尝试传递-fPIC标志,并且在构建libA.so文件时没有运气,我总是可以在libA.so中看到TEXTREL条目文件。我确定它是由于那些新的静态库,因为我之前使用的是libA而没有任何问题。 我试过的其他事情:尝试将gnutls构建为共享库,生成的libA.so现在没有文本重定位但仍然无法在运行时加载,因为gnutls所以文件有一个版本(例如libgnutls.so.3.0)和Android不支持版本化库。

具体问题:我该如何:1。将gnutls作为静态库构建而不进行文本重定位或2.将其构建为没有soname的共享库?

编辑:我在openconnect邮件列表中看到了相同的question,但没有明确说明如何在本机代码中修复TEXTREL"。

我已经看到了有关此questionthis问题的文本重定位问题的其他答案,但由于我使用了最新的NDK版本并通过了PIC,因此没有任何帮助旗帜已经

2 个答案:

答案 0 :(得分:1)

您无法加载需要文本重定位的库:

  

从API 23开始,共享对象不得包含文本重定位。也就是说,代码必须按原样加载,不得修改。

source

<强>数目:

  

如何在没有文本重定位的情况下将gnutl构建为静态库?

-fPIC无法阻止所有文字重定位。在某些情况下,如果您的库使用内联asm,编译器将无法使其与位置无关(PIC)。但是,如果您确定您的库可以独立于位置,则问题可能出现在构建配置中。

如果没有,您应该阻止您的库使用文本重定位。幸运的是,有一个很棒的wiki页面可以解释如何在Gentoo Wiki中进行操作。

  

如何将其构建为没有soname的共享库?

您可以使用:gcc -shared -Wl,-soname,your_soname设置您的soname。

答案 1 :(得分:0)

我终于明白了。由于gnutls依赖于荨麻和gmp,而荨麻依赖于gmp,我必须将gmp构建为共享库,其余部分作为静态构建。由于libgmp是唯一一个没有sonames的建筑,所以我没有问题以这种方式构建它。所以这是我的最终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)