NDK开发笔记——Android使用openssl

Android自身使用了谷歌的openssl分支boringssl,因此,如果要在Android中使用openssl,需要编译成静态库集成在自己的程序当中。

为Android编译openssl,首先需要获取到openssl的源代码和Android ndk,利用ndk中的交叉编译工具链编译出需要的openssl库。具体的配置可参照https://www.jianshu.com/p/b790c548e787,我使用的ndk版本是r17b,openssl版本是1.1.0h

这里需要注意的是的Android NDK可能会缺少头文件,交叉工具链默认的包含目录是没有需要的包含目录的,需要手动添加

export C_INCLUDE_PATH='$ANDROID_NDK_ROOT/sysroot/usr/include/'

这里还可能遇到缺少asm目录下的头文件,这些头文件可以在ndk目录里找到对应工具链的asm目录拷贝出去,编译时缺少的头文件都可以在该文件夹下搜索并复制到对应目录。

编译完之后可能会有链接的问题,如

./libcrypto.a(bio_cb.o):bio_cb.c:function BIO_debug_callback: error: undefined reference to 'stderr'

这个问题跟编译选择的对应Android版本有关,在NDK的stdio.h中有如下的定义

#if __ANDROID_API__ >= __ANDROID_API_M__
extern FILE* stdin __INTRODUCED_IN(23);
extern FILE* stdout __INTRODUCED_IN(23);
extern FILE* stderr __INTRODUCED_IN(23);

/* C99 and earlier plus current C++ standards say these must be macros. */
#define stdin stdin
#define stdout stdout
#define stderr stderr
#else
/* Before M the actual symbols for stdin and friends had different names. */
extern FILE __sF[] __REMOVED_IN(23);

#define stdin (&__sF[0])
#define stdout (&__sF[1])
#define stderr (&__sF[2])
#endif

由于openssl编译时没有android api宏,当编译的目标版本小于android m也就是23的时候,编译会报错,这时编译指定android的版本大于23即可,这样做会对兼容性产生什么影响尚未验证。

编译成功生成了.a文件之后,将其放入app的工程中,可能也会产生各种编译的错误,这里需要调整sdk的版本和最小兼容版本,具体能兼容到哪个版本待验证。

编译成功之后运行时可能会产生java.lang.UnsatisfiedLinkError错误,大意是64位程序引用32位库的问题,

在生成的apk的lib中会有各个平台的文件夹比如armv8这里需要在build.gradle中写入

android {
    ...
    defaultConfig {
        ...
        ndk {
            abiFilter("armeabi-v7a")
        }
    }
}
来过滤掉其它的库

在gradle.properties中添加

android.useDeprecatedNdk=true

猜你喜欢

转载自blog.csdn.net/hnlylyb/article/details/80709013