Issue
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: libA.so: has text relocations
I've tried to pass the -fPIC
flag when building the static libraries (.a files) and when building the libA.so file with no luck, I can always see TEXTREL entries in libA.so 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 libA.so now had no text relocations but would still fail to load at runtime because the gnutls so files have a version (e.g libgnutls.so.3.0) 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
Solution
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 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)
Answered By - Nonos
0 comments:
Post a Comment
Note: Only a member of this blog may post a comment.