【问题标题】:openSSL using Android's NDK problemsopenSSL 使用 Android 的 NDK 问题
【发布时间】:2012-05-04 08:12:22
【问题描述】:

我有以下情况, 我正在移植一个使用 OpenSSL 进行 AES 加密的应用程序,我已经编译了所有内容,但是链接器失败了。情况如下: 1. 我写了一个简单的 JNI 包装器:

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 时,它会构建所有拇指,因此编译器会正确编译它们。 接下来我需要为android移植openssl,我使用了这个OpenSSL for Android 它就像一个带有简单 ndk-build 的字符(当然在项目的根目录中)并构建 libssl.so 和 libcrypto.so

所以我需要将两者连接起来。我发现连接构建脚本是一个挑战,以便一个 ndk-build 编译并链接所有内容(如果有人有时间,我将不胜感激一个简单的示例项目)

所以我将编译后的 libssl 和 libcrypto .so 文件复制到 jni/includes/prebuilt 中,并希望将它们包含在项目中,以便链接器能够最终创建我将在最后使用的 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-build 时,我感到很失望

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 文件返回完全错误的路径... 任何帮助将不胜感激!

【问题讨论】:

    标签: android android-ndk openssl android-ndk-r7


    【解决方案1】:

    这里是解决方案,更新到 NDK8c

    零步:下载并修复 Android NDK 我不知道如何,但 ndk 有一个非常有趣的缺陷,(在我看来)不允许你编译很多东西,所以为了能够编译 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 编译: 编译找到的移植版本here 或者下载官方1.0.0c版本的OpenSSL,然后使用我为Android兼容版本链接的github中提供的手册为android编译它

    所以下一步是获取 libssl.solibcrypto.so 并将它们放在NDK文件夹中以便于访问,因此请从

    复制它们
    openssl-folder/libs/armeabi/
    

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

    这样编译时,您可以使用简单的链接器开关 -lssl -lcrypto 包含库

    第二步:获取 Curl 的 here

    的最新来源

    在 Docs/INSTALL 中打开文件并按照制作独立工具链所需的步骤并将其放入所需的文件夹中,然后是棘手的部分,我需要有 android 的源代码才能继续配置,即使我有一个独立编译的openssl你也可以从那里包含头文件,无论如何这是更复杂的版本,所以你选择你做什么,我没有选择逃避它们,所以你可以去Google AOSP site并通过步骤来构建并初始化环境。

    所以它会是这样的:

    1.下载,

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

      ~: build/envsetup.sh;午餐 1;制作;

    所以最后我们需要编译带有 SSL 支持的 curl,所以,

    第三步

    解压 curl 到想要的文件夹 (我特别希望禁用除 http/s 之外的所有内容,以使库尽可能小,这意味着大约 300k,如果您想要在您的库中使用更多协议,请删除所需协议的 --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
    

    就是这样.. 获取文件,然后编译 :)

    【讨论】:

    • 如果解决了,您可以将您的解决方案标记为答案...一切顺利
    • 将修复程序应用于 __gsml 后,我收到错误消息:Android NDK:您的 APP_BUILD_SCRIPT 指向未知文件:/Android.mk d:/Development/android/android-ndk-r8c/build/core /add-application.mk:165: *** Android NDK: Aborting...。停止。你在哪个平台上运行这个?视窗?是否可以将 libcrypto.so libssl.so 上传到某个地方?
    • 你能告诉我们你是如何在 Android.mk 文件中链接所有这些的吗?
    【解决方案2】:

    @Tancho

    我对您提到的 __gmsl:512 行进行了更改。虽然它允许 OpenSSL 进行编译,但它也通过 $(BUILD_EXECUTABLE) 破坏了可执行文件的构建。在更改之前,我的简单 hello world 应用程序编译并运行,但在更改之后它编译但在我的 Nexus 上运行它会导致段错误。

    还原更改,一切都会恢复正常。我不知道如何解决这个问题,我真的不知道那条线的作用,但这只是对任何进行该更改的人的一个小警告。

    【讨论】:

    • 有趣.. 我做了同样的改变。到目前为止,这一切都运作良好,但仍然保持谨慎有助于......
    • 我最终通过以下替换解决了这个问题:从 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。
    猜你喜欢
    • 2012-08-05
    • 1970-01-01
    • 2015-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多