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

Shared library using static gnutls library has text relocations

本文关键字:文本 功能 定位 gnutls 静态 共享      更新时间:2023-10-16

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

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

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

在构建静态库时,我试图通过-fPIC标志。以及在构建libA. a文件时。如果不走运,我总能在libA中看到TEXTREL条目。所以文件。我确信这是由于那些新的静态库,因为我以前使用libA没有问题。我尝试的另一件事是:尝试将gnutls构建为共享库,生成libA。所以现在没有文本重定位,但仍然会在运行时加载失败,因为gnutls文件有一个版本(例如libgnutls.so.3.0), Android不支持版本库。

具体问题:我怎么能:将gnutls构建为静态库,不需要文本重定位;将其构建为没有名称的共享库?

编辑:我在openconnect邮件列表中看到同样的问题,但没有明确的方法如何"首先在本机代码中修复TEXTRELs"。

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

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

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

(源)

答案:

如何构建gnutls作为没有文本重定位的静态库?

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

如果没有,你应该阻止你的库使用文本重定位。幸运的是,在Gentoo wiki中有一个很棒的wiki页面解释了如何做到这一点。

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

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

我终于想通了。因为gnutls依赖于荨麻和gmp,而荨麻依赖于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)