2012-04-23 105 views
3

我有以下情况, 我正在移植一个使用OpenSSL进行AES加密的应用程序,我已经编译了一切,但链接程序失败。这种情况如下: 1.我写了一个JNI包装,简单地做:使用Android的NDK问题的openSSL

private native String cipherString(String plainData, int datasize, String password, int passSize); 
private native String decipherString(String cipheredData, int datasize, String password, int passSize); 

下一个我有一个C++文件,我称之为有适当的JNI sintax它转换的jstring为char *和所有其他必要转换,并调用另一个实际导入openssl头文件(存在并考虑)的cpp文件,并调用openssl方法进行加密和解密。

所以当我调用ndk-build时,它会构建所有的拇指,因此编译器会正确编译它们。 接下来我需要端口OpenSSL,以便Android和我用这个OpenSSL for Android 它的工作原理是用一个简单的NDK构建一个字符(在项目的根着,当然),并建立libssl.so和libcrypto.so

所以我需要连接这两个..我发现连接构建脚本是一个挑战,所以一个ndk-build编译和链接所有东西(如果有人有时间,我会感激一个简单的示例项目)

所以我复制了jni/includes/prebuilt中编译的libssl和libcrypto .so文件,并且希望将它们包含在链接器的项目中,以便能够最终创建我将在最后使用的lib。

我有以下Android.mk文件

LOCAL_PATH := $(call my-dir) 
include $(CLEAR_VARS) 
include $(LOCAL_PATH)/includes/build/common.mk 
include $(LOCAL_PATH)/includes/build/common_includes.mk 
APP_STL := gnustl_static 

LOCAL_MODULE := packer 
LOCAL_SRC_FILES := modules/cipher/wrapper.cpp \ 
        ... #rest of the cpp code 

LOCAL_C_INCLUDES += $(LOCAL_PATH)/includes/openssl 
LOCAL_SHARED_LIBRARIES := $(LOCAL_PATH)/includes/precompiled/libssl.so \ 
      $(LOCAL_PATH)/includes/precompiled/libcrypto.so 
LOCAL_SHARED_MODULES := sslx cryptox 
include $(BUILD_SHARED_LIBRARY) 

LOCAL_PATH := $(call my-dir) 
include $(CLEAR_VARS) 
LOCAL_MODULE := sslx 
LOCAL_SRC_FILES := $(LOCAL_PATH)/includes/precompiled/libssh.so 
include $(PREBUILT_SHARED_LIBRARY) 

LOCAL_PATH := $(call my-dir) 
include $(CLEAR_VARS) 
LOCAL_MODULE := cryptox 
LOCAL_SRC_FILES := $(LOCAL_PATH)/includes/precompiled/libssh.so 
include $(PREBUILT_SHARED_LIBRARY) 

,并呼吁NDK建造时,我得到一个dissapointing

sslx: LOCAL_SRC_FILES points to a missing file. Check that /home/user/Development/Tools/sdk/android/ndk/build/core//home/user/Development/Tools/sdk/android/ndk/build/core/includes/precompiled/libssh.so exists or that its path is correct. Aborting . Stop. 

,你已经可以猜到的路径是完全错误的,什么混淆我是$ {LOCAL_PATH}返回第一批包含的正确路径和.so文件的完全错误的路径... 任何帮助将非常感激!

回答

8

这里是解决方案,更新NDK8c

一步零:下载并修复了Android NDK 我不知道怎么样,但NDK有一个很有趣的缺陷,这(在我oppinion)不允许你需要编译很多东西,所以为了能够编译OpenSSL,你需要做一个小小的修复,在你保存工具的时候提取ndk8c,然后编辑文件: android-ndk-r8c/build/gmsl/__ gmsl 512行: 更改行

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

与线

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

,你是好去!

一步一个:下载OpenSSL和编译的Android版本:0​​要么编译移植版本中发现here 或下载的官方1.0。OpenSSL的0℃至版本,然后用我联系为Android兼容版本

因此,下一步是让libssl.solibcrypto.so 并把github上提供的手动编译为Android在编译时,他们为方便NDK的文件夹,所以从

openssl-folder/libs/armeabi/ 

将它们复制到

android-ndk-r8c/platforms/android-8/arch-arm/usr/lib 

这样哟ü可以用一个简单的链接器开关包括库-lssl -lcrypto

第二步:获得卷曲的最新源here

打开文件文档/安装,然后做出独立的工具链所需的步骤和放在你想要的文件夹中,然后是棘手的部分,我需要让android的源代码继续配置,即使我有一个独立编译的openssl,你也可以从那里包含头文件,在任何情况下,这是更复杂版本,所以你选择你做什么,我没有选择逃避他们,所以你可以去Google AOSP site,并通过步骤来bui ld并初始化环境。

所以它会是这样的:

1.download,

  1. 转到源代码的根目录并运行:

    〜:建/ envsetup.sh;午餐1;使;

所以最后我们需要编译卷曲支持SSL,因此,

第三步

提取物卷曲到所需的文件夹 (我除了HTTP禁止一切的具体愿望/ s来保持库尽可能小,大概约300k,如果你想在你的lib里有更多的协议,删除所需协议的--disable-protocol) 运行下面的命令:

make clean 

export PATH=/opt/arm-linux-androideabi-4.4.3/bin:$PATH 

export LDFLAGS="\ 
-lssl \ 
-lcrypto \ 
-L/home/user/Development/Tools/sdk/android/ndk/platforms/android-8/arch-arm/usr/lib" 

export CFLAGS="\ 
-I/home/user/Development/AOSP/2.3.7/system/core/include \ 
-I/home/user/Development/Tools/sdk/android/ndk/platforms/android-8/arch-arm/usr/include" 

./configure --host=arm-linux-androideabi \ 
--with-ssl=/home/user/Development/Projects/portingLibs/openssl-android-master \ 
--disable-ftp \ 
--disable-gopher \ 
--disable-file \ 
--disable-imap \ 
--disable-ldap \ 
--disable-ldaps \ 
--disable-pop3 \ 
--disable-proxy \ 
--disable-rtsp \ 
--disable-smtp \ 
--disable-telnet \ 
--disable-tftp \ 
--without-gnutls \ 
--without-libidn \ 
--without-librtmp \ 
--disable-dict 


make 



Note that in the block above, if you don't want to use the AOSP source, you could switch 

-I/home/user/Development/AOSP/2.3.7/system/core/include \ 

with the include folder for your ssl distribution. 

所以最后您有: 静:

curl-7.28.1/lib/.libs/libcurl.a 

和共享:

curl-7.28.1/lib/.libs/libcurl.so.5.3 

所以这是它..拿那个文件,然后进行编译:)

+0

如果解决了,您可以将您的解决方案标记为答案...一切顺利 – 2012-04-24 10:02:37

+0

将修复应用于__gsml后,我收到错误:Android NDK:您的APP_BUILD_SCRIPT指向未知文件:/Android.mk d :/Development/android/android-ndk-r8c/build/core/add-application.mk:165:*** Android NDK:正在中止......。停止。 在哪个平台上运行这个?视窗?是否有可能将libcrypto.so libssl.so上传到某处? – tmanthey 2013-01-18 12:16:16

+0

你能向我们展示如何在Android.mk文件中链接所有这些吗? – 2014-07-10 10:50:01

0

@Tancho

我对您提到的__gmsl:512行进行了更改。虽然它允许OpenSSL进行编译,但也会以$(BUILD_EXECUTABLE)打破可执行文件的构建。在更改之前,我的简单的hello world应用程序编译并运行,但在更改之后,它会编译但在我的Nexus结果中运行它,发生seg故障。

恢复变化,一切都很好。我不知道如何解决这个问题,我真的不知道这条线是干什么的,但这只是对任何人做出这种改变的一点警告。

+0

有趣..我做了同样的改变。到目前为止,这一切都运行良好,但仍然处于谨慎的帮助... – Tancho 2013-01-17 09:28:01

+0

我做了以下替换修复此问题:从'int_encode = $(__ gmsl_tr1)$(wordlist 1,$ 1,$ (__gmsl_input_int))'到'int_encode = $(__ gmsl_tr1)$(wordlist 1,$(if $ 1,$ 1,0),$(__ gmsl_input_int))'这很好地处理了$ 1是空的,在这种情况下返回0。 – OwainD 2013-03-19 18:05:41