openssl for android
一、编译环境
ubuntu 20.04
ndk r21
openssl-1.1.1f
二、编译过程
1、下载源码
本文档在2020-06-03最新的源码版本为openssl-1.1.1f
root@ubuntu:/home/openssl-android# wget https://www.openssl.org/source/old/1.1.1/openssl-1.1.1f.tar.gz
2、解压源码
root@ubuntu:/home/openssl-android# tar -zxvf openssl-1.1.1f.tar.gz
3、根据NOTE.ANDROID添加环境变量
在/etc/profile文件中添加,然后source /etc/profile生效环境变量。
export ANDROID_NDK_HOME=/home/aiwen/Android/android-ndk-r21
export PATH=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$ANDROID_NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86_64/bin:$PATH
4、编译平台说明
安卓平台使用Configure来配置和生成Makefile文件。
root@ubuntu:/home/openssl-android/openssl-1.1.1f# ./Configure
Usage: Configure [no-<cipher> ...] [enable-<cipher> ...] [-Dxxx] [-lxxx] [-Lxxx] [-fxxx] [-Kxxx] [no-hw-xxx|no-hw] [[no-]threads] [[no-]shared] [[no-]zlib|zlib-dynamic] [no-asm] [no-egd] [sctp] [386] [--prefix=DIR] [--openssldir=OPENSSLDIR] [--with-xxx[=vvv]] [--config=FILE] os/compiler[:flags]
#只需要编译以下常用的平台就可以了。
pick os/compiler from:
android-arm android-arm64 android-x86 android-x86_64
其他说明阅读以下三个文件
NOTES.ANDROID
INSTALL
NOTES.PERL
5、新建编译输目录
root@ubuntu:/home/openssl-android/openssl-1.1.1f# mkdir output
root@ubuntu:/home/openssl-android/openssl-1.1.1f# cd output
root@ubuntu:/home/openssl-android/openssl-1.1.1f# mkdir x86 x86_64 arm arm64
6、编译x86平台
执行下面的命令,生成Makefile文件,然后执行make,让编译的文件放在/output/x86目录下
root@ubuntu:/home/openssl-android/openssl-1.1.1f# ./Configure android-x86 -D__ANDROID_API__=23 --prefix=/home/openssl-android/openssl-1.1.1f/output/x86
Configuring OpenSSL version 1.1.1f (0x1010106fL) for android-x86
Using os-specific seed configuration
Creating configdata.pm
Creating Makefile
**********************************************************************
*** ***
*** OpenSSL has been successfully configured ***
*** ***
*** If you encounter a problem while building, please open an ***
*** issue on GitHub <https://github.com/openssl/openssl/issues> ***
*** and include the output from the following command: ***
*** ***
*** perl configdata.pm --dump ***
*** ***
*** (If you are new to OpenSSL, you might want to consult the ***
*** 'Troubleshooting' section in the INSTALL file first) ***
*** ***
**********************************************************************
root@ubuntu:/home/openssl-android/openssl-1.1.1f# make && make install
编译结果
root@ubuntu:/home/openssl-android/openssl-1.1.1f# ls output/x86
bin include lib share ssl
root@ubuntu:/home/openssl-android/openssl-1.1.1f# ls output/x86/lib
engines-1.1 libcrypto.so libssl.a libssl.so.1.1
libcrypto.a libcrypto.so.1.1 libssl.so pkgconfig
7、编译其他平台
需要新的解压源码,不能在同上一个平台的源码上编译。可能是Configure生成的文件没有正常更改。
否则会报如下错误。原因未知。
clang: error: linker command failed with exit code 1 (use -v to see invocation)
x86_64
root@ubuntu:/home/openssl-android/openssl-1.1.1f# ./Configure android-x86_64 -D__ANDROID_API__=23 --prefix=/home/openssl-android/openssl-1.1.1f/output/x86_64
arm
root@ubuntu:/home/openssl-android/openssl-1.1.1f# ./Configure android-arm -D__ANDROID_API__=23 --prefix=/home/openssl-android/openssl-1.1.1f/output/arm
arm64
root@ubuntu:/home/openssl-android/openssl-1.1.1f# ./Configure android-arm64 -D__ANDROID_API__=23 --prefix=/home/openssl-android/openssl-1.1.1f/output/arm64
三、移植到Android Studio
1、Android Studio版本
2、工程原生app build.gradle
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "org.hmsp.myapplication"
minSdkVersion 23
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
cmake {
cppFlags ""
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
3、添加静态库文件
在cpp目录下新建libs/x86文件夹。
将编译好的libcrypto.a和libssl.a两个静态库放进libs/x86目录中。
4、添加openssl头文件
将编译好的include文件夹复制到cpp目录下。
5、编写CMakeLists.txt文件
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
#将openssl的头文件目录包含进来
include_directories(include)
#添加两个静态库文件
add_library(
openssl-crypto
STATIC
IMPORTED)
set_target_properties(
openssl-crypto
PROPERTIES
IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcrypto.a)
add_library(
openssl-ssl
STATIC
IMPORTED)
set_target_properties(
openssl-ssl
PROPERTIES
IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libssl.a)
add_library(
native-lib
SHARED
native-lib.cpp )
find_library(
log-lib
log )
target_link_libraries(
native-lib
${log-lib}
openssl-ssl
openssl-crypto)
6、在app build.gradle配置NDK编译平台
ndk {
abiFilters 'x86'
}
7、在app build.gradle配置CMake编译参数
cmake {
cppFlags "-frtti -fexceptions"
}
8、验证openssl版本
#include <jni.h>
#include <string>
#include "openssl/crypto.h"
extern "C" JNIEXPORT jstring JNICALL
Java_org_hmsp_myapplication_MainActivity_stringFromJNI(
JNIEnv* env,
jobject /* this */) {
std::string hello = "Hello from C++";
//return env->NewStringUTF(hello.c_str());
return env->NewStringUTF(OpenSSL_version(OPENSSL_VERSION));
}
9、运行结果
10、完整的配置文件和工程目录
(1)工程目录
(2)build.gradle(app)文件
apply plugin: 'com.android.application'
android {
compileSdkVersion 29
buildToolsVersion "29.0.3"
defaultConfig {
applicationId "org.hmsp.myapplication"
minSdkVersion 23
targetSdkVersion 29
versionCode 1
versionName "1.0"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
externalNativeBuild {
ndk {
abiFilters 'x86'
}
cmake {
cppFlags "-frtti -fexceptions"
}
}
}
buildTypes {
release {
minifyEnabled false
proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'
}
}
externalNativeBuild {
cmake {
path "src/main/cpp/CMakeLists.txt"
version "3.10.2"
}
}
}
dependencies {
implementation fileTree(dir: "libs", include: ["*.jar"])
implementation 'androidx.appcompat:appcompat:1.1.0'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
testImplementation 'junit:junit:4.13'
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
androidTestImplementation 'androidx.test.espresso:espresso-core:3.2.0'
}
(3)CMakeLists.txt文件
# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)
#将openssl的头文件目录包含进来
include_directories(include)
#添加两个静态库文件
add_library(
openssl-crypto
STATIC
IMPORTED)
set_target_properties(
openssl-crypto
PROPERTIES
IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libcrypto.a)
add_library(
openssl-ssl
STATIC
IMPORTED)
set_target_properties(
openssl-ssl
PROPERTIES
IMPORTED_LOCATION
${CMAKE_SOURCE_DIR}/libs/${ANDROID_ABI}/libssl.a)
add_library(
native-lib
SHARED
native-lib.cpp )
find_library(
log-lib
log )
target_link_libraries(
native-lib
${log-lib}
openssl-ssl
openssl-crypto)