Nonos Nonos - 10 months ago 95
C++ Question

Shared library using static gnutls library has text relocations

Problem: I need to port gnutls to Android to be used in a shared library (say library A) I'm using in my Android application.

What I've tried: I've modified the make file for openconnect to generate a .a static library file for gnutls and its dependencies (libgmp, libnettle and libhogweed), I used them to build static libraries in my Android project and referenced them in the shared library A. Code builds and installs fine but on M+ devices I get the following error at runtime:

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

I've tried to pass the
flag when building the static libraries (.a files) and when building the file with no luck, I can always see TEXTREL entries in file. I'm sure it is due to the those new static libraries since I was using libA before with no issues.
Other thing I tried: tried building gnutls as a shared library, the generated now had no text relocations but would still fail to load at runtime because the gnutls so files have a version (e.g and Android does not support versioned libraries.

Specific question: How can I either: 1.Build gnutls as a static library without text relocations or 2. Build it as a shared library with no soname?

Edit: I see the same question asked on the openconnect mailing list but no clear way on how to "fix the TEXTRELs in the native code first".

I have seen other answers for problems with text relocations like this question and this question but that didn't help since I'm using the latest NDK build and passing the PIC flag already


I finally figured it out. Since gnutls depends on nettle and gmp while nettle depends on gmp as well I had to build gmp as a shared library and the rest as static. Since libgmp was the only one building without sonames I had no problem to build it this way. So this is my final

LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE := libgmp

include $(CLEAR_VARS)
LOCAL_MODULE := libhogweed
LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libhogweed.a

include $(CLEAR_VARS)
LOCAL_MODULE := libnettle
LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libnettle.a

include $(CLEAR_VARS)
LOCAL_MODULE := libgnutls
LOCAL_SRC_FILES := lib/$(TARGET_ARCH_ABI)/libgnutls.a
LOCAL_STATIC_LIBRARIES := libhogweed libnettle