Android教程網
  1. 首頁
  2. Android 技術
  3. Android 手機
  4. Android 系統教程
  5. Android 游戲
 Android教程網 >> Android技術 >> 關於Android編程 >> Openssl如何移植到Android

Openssl如何移植到Android

編輯:關於Android編程

Openssl移植到Android都是使用別人提好(從Android源碼)的Openssl代碼,方法簡單但過程不那麼順利,因為Openssl版本變動太頻繁了,再加上NDK一堆BUG,極不願意去調試原始配置,單單Openssl的模塊編譯前後就等了兩個月直到Google推出NDK新版本R8C才編譯通過。因為原生程序應用到很多Openssl簽名、驗證算法函數,就連Openssl的版本升級一下往往都要修改一些代碼才能通過。

一、下載Openssl最新版本
可選的Openssl Android版本下載地址:

Openssl 1.0.0a:

https://github.com/guardianproject/openssl-android

Openssl 1.0.1c:

https://github.com/aluvalasuman/OpenSSL1.0.1cForAndroid

本文將要使用的Openssl版本為1.0.1c,前一1.0.0a版本未驗證通過(NDKr8b),編譯時會出現下文的編譯錯誤。所以改用較新版本,目前已知1.0.1c在NDK r8b上編譯會有很多問題,不是Openssl工程有兼容BUG就是NDK版本有BUG,反正不是那麼容易調試通過。

二、編譯過程
本文編譯使用最新的NDK r8c(Ubuntu 12.04),下載Openssl android工程後解壓,可以看到完整的NDK工程,簡單的編譯過程如下:

進入解壓目錄,執行:
$NDK_HOME/ndk-build clean
$NDK_HOME/ndk-build
編譯結果在obj目錄下(libcrypto-static.a和libssl-static.a或是libcrypto.so和libssl.so)
把結果拷貝出來放到自己的Android工程Helloworld對應目錄下進行調用即可。
上述步驟4編譯出Openssl的鏈接庫,一般拷貝到ndk_r8c\platforms\android-10\arch-arm\usr\lib目錄下(僅為示例),然後把openssl根下的include目錄都拷貝出去就是編譯頭文件,這樣就可以構建自己的helloworld工程了,在helloworld的Android.mk中增加類似如下調用:

LOCAL_LDLIBS := -L$(SYSROOT)/lib/ -llog -lcrypto -lssl

三、常見錯誤
以下編譯錯誤,有的在1.0.0a版本中遇到,有的是在NDK r8b環境下遇到,此間涉及到OpenSSL版本問題、GCC版本問題、NDK版本BUG問題,等等都混到一起總結方便對應處理。

1、undefined reference to `zError'
openssl 庫時錯誤如下:

SharedLibrary : libssl.so
Executable : openssl
/root/android-ndk-r8b/toolchains/arm-linux-androideabi-4.6/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.6.x-google/../../../../arm-linux-androideabi/bin/ld: warning: libz.so, needed by ./obj/local/armeabi/libcrypto.so, not found (try using -rpath or -rpath-link)

./obj/local/armeabi/libcrypto.so: undefined reference to `zError'
./obj/local/armeabi/libcrypto.so: undefined reference to `inflateEnd'
./obj/local/armeabi/libcrypto.so: undefined reference to `deflate'
./obj/local/armeabi/libcrypto.so: undefined reference to `deflateInit_'
./obj/local/armeabi/libcrypto.so: undefined reference to `inflate'
./obj/local/armeabi/libcrypto.so: undefined reference to `deflateEnd'
./obj/local/armeabi/libcrypto.so: undefined reference to `inflateInit_'
collect2: ld returned 1 exit status
解決辦法:

1、$NDK_HOME/ndk-build NDK_TOOLCHAIN_VERSION=4.4.3

$NDK_HOME/ndk-build NDK_TOOLCHAIN=arm-linux-androideabi-4.4.3

該方法參考來自:android-ndk-r8b/doc/NDK-BUILD.html 說明,ndk-build可以攜帶 NDK_XXX這樣的參數,來指定編譯環境版本信息。具體參數有哪些?目前可以通過android-ndk-r8b/build/core/init.mk裡查詢到一些NDK_開頭的參數。

2、在openssl的jni目錄下的Application.mk中增加:

APP_PLATFORM := android-8

3、在openssl根下的android-config.mk中增加:

APP_ABI := armeabi armeabi-v7a

該參考來源android-ndk-r8b/docs/APPLICATION-MK.html

2、Unknown EABI object attribute 44
SharedLibrary : libssl.so
/root/android-ndk-r8b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld: Warning: /root/android-ndk-r8b/platforms/android-8/arch-arm/usr/lib/crtend_so.o: Unknown EABI object attribute 44
Executable : openssl
/root/android-ndk-r8b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld: Warning: /root/android-ndk-r8b/platforms/android-8/arch-arm/usr/lib/crtend_android.o: Unknown EABI object attribute 44
Install : openssl => /root/aluvalassuman/libs/armeabi/openssl
Install : libssl.so => /root/aluvalassuman/libs/armeabi/libssl.so
Compile thumb : ssltest <= ssltest.c
Executable : ssltest
/root/android-ndk-r8b/toolchains/arm-linux-androideabi-4.4.3/prebuilt/linux-x86/bin/../lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin/ld: Warning: /root/android-ndk-r8b/platforms/android-8/arch-arm/usr/lib/crtend_android.o: Unknown EABI object attribute 44
Install : ssltest => /root/aluvalassuman/libs/armeabi/ssltest
解決辦法:

4.4.3似乎跟鏈接庫的編譯環境可能對不上(44沖突),網上有說改成4.6就沒問題了,不會出現該提示,但是4.6支持STL有BUG啊?

crypto/Android.mk 大約535行,添加:

LOCAL_EXPORT_LDLIBS := -lz

注意有沒添加以下兩個靜態庫,大約576行,添加(暫時不用):

LOCAL_LDLIBS := -lz –ldl

3、build/gmsl/__gmsl:512: *** non-numeric second
Complile Openssl:

Error:
build/gmsl/__gmsl:512: *** non-numeric second
Changes:

I changed the file __gmsl, the second wordlist argument(line 512),
and it's running my jni example without errors:

int_encode = $(__gmsl_tr1)$(wordlist 1, $1,$(__gmsl_input_int))

to:

int_encode = $(__gmsl_tr1)$(wordlist 1,$(words $1),$
(__gmsl_input_int))
 

  1. 上一頁:
  2. 下一頁:
熱門文章
閱讀排行版
Copyright © Android教程網 All Rights Reserved