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

Shared library using static gnutls library has text relocations

问题: 我需要将 gnutls 移植到 Android 以便在我的 [=39= 中使用的共享库(比如库 A)中使用]申请。

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

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

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

具体问题: 我怎样才能:1.Build gnutls 作为没有文本重定位的静态库或者 2. 将它构建为没有 soname 的共享库?

编辑:我在 openconnect 邮件列表中看到了相同的 question 问询,但没有明确的方法 "fix the TEXTRELs in the native code first"。

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

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

Starting with API 23, shared objects must not contain text relocations. That is, the code must be loaded as is and must not be modified.

(source)

答案:

How can I build gnutls as a static library without text relocations?

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

如果不是,您应该阻止您的图书馆使用文本重定位。幸运的是,Gentoo Wiki.

中有一个很棒的 wiki 页面解释了如何做到这一点

How can I build it as a shared library with no soname?

您可以设置您的声名:gcc -shared -Wl,-soname,your_soname

我终于明白了。由于 gnutls 依赖于 nettle 和 gmp,而 nettle 也依赖于 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)