2016-08-30 65 views
3

问题:我需要将gnutls移植到Android中以便在共享库中使用(称为库A)我正在使用我的Android应用程序。使用静态gnutls库的共享库有文本重定位

我已经试过什么:我已经修改了make file为openconnect来生成GNUTLS和它的依赖(libgmp,libnettle和libhogweed)以.a静态库文件,我用它们来构建静态库我Android项目,并引用他们在共享库A.代码构建和安装正常,但在M +的设备,我得到以下运行时错误:

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

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

具体问题:我该怎么做:1.将gnutls作为静态库而不需要文本重定位或者2.将它构建为没有soname的共享库?

编辑:我看到相同的question问在openconnect邮件列表上,但没有清楚的方法如何“先修复本地代码中的TEXTREL”。

我看到其他的答案像这样questionthis问题与文本重定位的问题,但没有帮助,因为我使用的是最新的NDK构建和传递PIC标志已经

+1

的可能的复制[libavcodec.so:具有文本重](http://stackoverflow.com/questions/32346402/libavcodec-so-has-text-relocations) –

+0

我不认为它是重复的,因为我使用最新的NDK构建并传递-fPIC标志来构建位置独立代码 – Nonos

+0

它真的和@RichardCritten提到的问题一样,请看一看在[本页](http://android-developers.blogspot.ru/2016/06/android-changes-for-ndk-developers.html)的“文本重定位(API 23以后实施)”部分,尽管接受对这个问题的回答只是一个解决方法,真正的事情是修复这个库,但这是特定于库的(从你有四个组合的事实开始)和依赖不知道你用来建立它的选项。 –

回答

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) 
1

您不能加载需要文本重定位的库:

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

source

答案:

我怎样才能建立GNUTLS作为静态库无文本重定位?

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

如果不是,您应该防止您的图书馆使用文本重定位。幸运的是,有一个伟大的wiki页面解释了如何在Gentoo Wiki中做到这一点。

我该如何将它构建为没有soname的共享库?

您可以将您的soname设置为:gcc -shared -Wl,-soname,your_soname

+0

对不起,但这个答案只是再次提出这个问题......请注意,我详细说明了问题中的问题,并且我明白了症状是什么,但给类似问题的答案对我的情况没有帮助,更具体地说,我表示我用-fPIC构建了应该防止文本重定位的文件,并且我使用最新的NDK构建了共享库 – Nonos

+0

'-fPIC'不能阻止所有文本重定位。如果你的库使用'inline asm',有时编译器将不能使它们成为'PIC'。因此,你应该自己解决这个问题。看看Gentoo的链接,看看如何去做。 –

+0

@Nonos我已经更新了答案。 –