3

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

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

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

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

4

2 回答 2

1

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

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

来源

答案:

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

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

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

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

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

于 2016-09-06T18:45:06.910 回答
0

我终于弄明白了。由于 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)
于 2016-09-14T22:24:10.970 回答