2016-08-30 157 views
3

問題:我需要將gnutls移植到Android中以便在共享庫中使用(稱爲庫A)我正在使用我的Android應用程序。使用靜態gnutls庫的共享庫有文本重定位

我已經試過什麼:我已經修改了make file爲openconnect來生成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如此的文件有一個版本(例如libgnutls.so.3.0)和Android不支持版本化的庫。

具體問題:我該怎麼做:1.將gnutls作爲靜態庫而不需要文本重定位或者2.將它構建爲沒有soname的共享庫?

編輯:我看到相同的question問在openconnect郵件列表上,但沒有清楚的方法如何「先修復本地代碼中的TEXTREL」。

我看到其他的答案像這樣questionthis問題與文本重定位的問題,但沒有幫助,因爲我使用的是最新的NDK構建和傳遞PIC標誌已經

+1

的可能的複製[libavcodec.so:具有文本重](http://stackoverflow.com/questions/32346402/libavcodec-so-has-text-relocations) –

+0

我不認爲它是重複的,因爲我使用最新的NDK構建並傳遞-fPIC標誌來構建位置獨立代碼 – Nonos

+0

它真的和@RichardCritten提到的問題一樣,請看一看在[本頁](http://android-developers.blogspot.ru/2016/06/android-changes-for-ndk-developers.html)的「文本重定位(API 23以後實施)」部分,儘管接受對這個問題的回答只是一個解決方法,真正的事情是修復這個庫,但這是特定於庫的(從你有四個組合的事實開始)和依賴不知道你用來建立它的選項。 –

回答

0

我終於明白了。由於gnutls依賴於蕁麻和gmp,而蕁麻依賴於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) 
1

您不能加載需要文本重定位的庫:

從API 23開始,共享對象不得包含文本重定位。也就是說,代碼必須按原樣加載並且不得修改。

source

答案:

我怎樣才能建立GNUTLS作爲靜態庫無文本重定位?

-fPIC無法防止所有文本重定位。在某些情況下,如果您的庫使用內聯asm,編譯器將無法使其與位置無關(PIC)。但是,如果您確定您的庫可以獨立於位置,則問題可能在您的構建配置中。

如果不是,您應該防止您的圖書館使用文本重定位。幸運的是,有一個偉大的wiki頁面解釋瞭如何在Gentoo Wiki中做到這一點。

我該如何將它構建爲沒有soname的共享庫?

您可以將您的soname設置爲:gcc -shared -Wl,-soname,your_soname

+0

對不起,但這個答案只是再次提出這個問題......請注意,我詳細說明了問題中的問題,並且我明白了症狀是什麼,但給類似問題的答案對我的情況沒有幫助,更具體地說,我表示我用-fPIC構建了應該防止文本重定位的文件,並且我使用最新的NDK構建了共享庫 – Nonos

+0

'-fPIC'不能阻止所有文本重定位。如果你的庫使用'inline asm',有時編譯器將不能使它們成爲'PIC'。因此,你應該自己解決這個問題。看看Gentoo的鏈接,看看如何去做。 –

+0

@Nonos我已經更新了答案。 –