在 macOS 上使用 NDK 和 OpenSSL 库,可以按照以下步骤进行操作,尤其是在 Android 项目中通过 JNI 调用 OpenSSL 时。我们将分步骤介绍如何编译 OpenSSL 以供 NDK 使用,并集成到 Android 项目中。
步骤 1: 准备环境
你已经在 macOS 上安装了 NDK,可以使用 ~/Library/Android/sdk/ndk/28.0.12433566 作为 NDK 路径。确保你的 macOS 系统上也安装了其他必需工具,比如 cmake 和 ninja,它们可以通过 Homebrew 安装:
bash
复制代码
brew install cmake ninja
步骤 2: 下载 OpenSSL 源代码
首先,从 OpenSSL 官方网站或 GitHub 下载最新的 OpenSSL 源代码。你可以使用 wget 或 git clone:
bash
复制代码
wget https://www.openssl.org/source/openssl-3.3.2.tar.gz
tar -xzvf openssl-3.3.2.tar.gz
cd openssl-3.3.2
或者使用 git:
bash
复制代码
git clone https://github.com/openssl/openssl.git
cd openssl
步骤 3: 配置并编译 OpenSSL for Android
使用 NDK 编译 OpenSSL 需要一些特定的配置。在 macOS 上,你可以使用 Android NDK 提供的工具链和环境。
-
创建一个用于交叉编译的环境:
你可以使用
ndk-build提供的standalone toolchain,也可以直接使用 NDK 的cmake配置。 -
为 Android 目标平台配置编译选项。创建配置脚本,指定 NDK 版本和目标架构(如
arm64-v8a)。以下是一个通用的配置命令:
bash
复制代码
./Configure android-arm64 --prefix=$HOME/openssl-android-arm64 --openssldir=$HOME/openssl-android-arm64
android-arm64是为arm64-v8a架构编译的配置。--prefix指定的是安装目录。--openssldir指定的是安装后的 OpenSSL 目录。
- 设置 NDK 工具链路径(假设你使用的是
28.0.12433566版本的 NDK):
bash
复制代码
export ANDROID_NDK_HOME=~/Library/Android/sdk/ndk/28.0.12433566
export PATH=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin:$PATH
- 编译 OpenSSL:
bash
复制代码
make
make install
这个过程会生成适用于 arm64-v8a 的 libcrypto.so 和 libssl.so 文件。
步骤 4: 将 OpenSSL 集成到 Android 项目中
- 将编译后的 OpenSSL 库文件
libcrypto.so和libssl.so放入 Android 项目的jniLibs目录。通常,你会将这些库文件放在以下目录结构中:
css
复制代码
app/
├── src/
│ └── main/
│ └── jniLibs/
│ ├── arm64-v8a/
│ │ ├── libcrypto.so
│ │ └── libssl.so
- 在你的 CMake 构建文件(
CMakeLists.txt)中,添加 OpenSSL 的库路径:
cmake
复制代码
set(OpenSSL_DIR ${CMAKE_SOURCE_DIR}/src/main/jniLibs/${ANDROID_ABI})
find_library(crypto-lib crypto PATHS ${OpenSSL_DIR})
find_library(ssl-lib ssl PATHS ${OpenSSL_DIR})
target_link_libraries(
your_target_name
${crypto-lib}
${ssl-lib}
)
- 在 JNI 代码中,包含 OpenSSL 的头文件并使用它们:
c
复制代码
#include <openssl/aes.h>
#include <openssl/evp.h>
#include <openssl/rand.h>
确保你也将 OpenSSL 头文件添加到 CMakeLists.txt 中:
cmake
复制代码
include_directories(${CMAKE_SOURCE_DIR}/src/main/jniLibs/include/openssl)
步骤 5: 编译和测试
- 使用
./gradlew build命令编译你的 Android 项目。 - 测试 OpenSSL 的功能是否正常。
此时打包出来的库是有调试码的,体积偏大 OpenSSL 源代码中包含了大量的测试代码和工具,它们在生成最终的库时并不是必须的。你可以通过一些配置选项来跳过这些测试代码的编译,从而减小生成的库的体积并加快编译速度。
禁用不必要的测试代码和工具的方法
-
no-tests:跳过测试代码的编译。- OpenSSL 提供了
no-tests选项,可以在配置时使用它来禁用所有的测试代码和相关的编译,从而避免编译测试程序。
- OpenSSL 提供了
-
no-fuzz:禁用 fuzzing 测试代码。- OpenSSL 包含 fuzz 测试代码,尽管没有直接的
no-fuzz选项,但 fuzz 相关代码一般可以通过配置disable-fuzz-libfuzzer或在build.info文件中手动排除(如前面提到的方法)。
- OpenSSL 包含 fuzz 测试代码,尽管没有直接的
修改配置命令
你可以尝试以下配置命令,将不必要的测试和工具都排除在外,仅编译需要的部分:
bash
复制代码
./Configure android-arm64 no-asm no-comp no-ec no-dh no-dsa no-rc4 no-des no-ssl no-fips no-tests --prefix=$HOME/openssl-android-arm64 --openssldir=$HOME/openssl-android-arm64 CFLAGS="-DNDEBUG -O3" LDFLAGS="-Wl,--strip-all"
配置参数解释:
参数解读
-
./Configure:- 这是运行 OpenSSL 的配置脚本,用于设置编译环境和选项。
-
android-arm:- 指定目标平台为 Android 的 ARM 架构。对应于
armeabi-v7a。
- 指定目标平台为 Android 的 ARM 架构。对应于
-
no-comp: 禁用压缩功能(如 Zlib 支持),减小库的体积。 -
no-ec:禁用椭圆曲线加密(Elliptic Curve Cryptography)相关的功能。 -
no-dh:禁用 Diffie-Hellman(DH)密钥交换算法。 -
no-dsa:禁用 DSA(数字签名算法)。 -
no-rc4:禁用 RC4 加密算法。 -
no-des:禁用 DES(数据加密标准)算法。 -
no-ssl:禁用 SSL(安全套接层)协议支持。 -
no-fips:禁用 FIPS(联邦信息处理标准)模块相关的功能。 -
no-tests:禁用测试代码的编译,避免生成任何测试程序,减小构建体积。 -
--prefix=$HOME/openssl-android-armv7:指定安装路径的前缀,将生成的库和头文件安装到$HOME/openssl-android-armv7目录下。 -
--openssldir=$HOME/openssl-android-armv7:指定 OpenSSL 配置文件(如openssl.cnf)的安装目录。 -
CFLAGS="-DNDEBUG -O3":-
CFLAGS用于设置编译器的选项:-DNDEBUG:禁用调试模式,意味着不会生成调试信息,有助于优化性能。-O3:启用最高级别的优化,编译器会尽可能优化生成的代码。
-
-
LDFLAGS="-Wl,--strip-all":-
LDFLAGS用于设置链接器的选项:-Wl,--strip-all:指示链接器去掉所有符号表和调试信息,以减小生成的库的体积。
-
armeabi-v7a 和 x86 的配置命令。它们的编译步骤和 arm64 类似,只需修改架构目标。
编译 armeabi-v7a
bash
复制代码
./Configure android-arm no-comp no-ec no-dh no-dsa no-rc4 no-des no-ssl no-fips no-tests --prefix=$HOME/openssl-android-armv7 --openssldir=$HOME/openssl-android-armv7 CFLAGS="-DNDEBUG -O3" LDFLAGS="-Wl,--strip-all"
编译 x86
bash
复制代码
./Configure android-x86 no-comp no-ec no-dh no-dsa no-rc4 no-des no-ssl no-fips no-tests --prefix=$HOME/openssl-android-x86 --openssldir=$HOME/openssl-android-x86 CFLAGS="-DNDEBUG -O3" LDFLAGS="-Wl,--strip-all"
总结:
android-arm用于编译armeabi-v7a。android-x86用于编译x86。- 这两个架构的命令和
android-arm64基本一致,只需根据不同的架构目标修改配置。
编译完成后,你可以运行以下命令以清理构建并开始编译:
bash
复制代码
make clean
make
make install
这样你就可以为这三个架构生成对应的 OpenSSL 库了。
总结:
通过禁用测试代码和不必要的加密功能,你可以显著减少 OpenSSL 编译的内容。no-tests 选项特别有用,可以直接跳过所有的测试代码编译。如果有其他需要调整的模块,也可以继续通过类似的 no- 选项来剔除。