编译openssl(跟着Chatgpt无脑操作,有问题继续问chatgpt)

578 阅读4分钟

在 macOS 上使用 NDK 和 OpenSSL 库,可以按照以下步骤进行操作,尤其是在 Android 项目中通过 JNI 调用 OpenSSL 时。我们将分步骤介绍如何编译 OpenSSL 以供 NDK 使用,并集成到 Android 项目中。

步骤 1: 准备环境

你已经在 macOS 上安装了 NDK,可以使用 ~/Library/Android/sdk/ndk/28.0.12433566 作为 NDK 路径。确保你的 macOS 系统上也安装了其他必需工具,比如 cmakeninja,它们可以通过 Homebrew 安装:

bash
复制代码
brew install cmake ninja

步骤 2: 下载 OpenSSL 源代码

首先,从 OpenSSL 官方网站或 GitHub 下载最新的 OpenSSL 源代码。你可以使用 wgetgit 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 提供的工具链和环境。

  1. 创建一个用于交叉编译的环境:

    你可以使用 ndk-build 提供的 standalone toolchain,也可以直接使用 NDK 的 cmake 配置。

  2. 为 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 目录。
  1. 设置 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
  1. 编译 OpenSSL:
bash
复制代码
make
make install

这个过程会生成适用于 arm64-v8alibcrypto.solibssl.so 文件。

步骤 4: 将 OpenSSL 集成到 Android 项目中

  1. 将编译后的 OpenSSL 库文件 libcrypto.solibssl.so 放入 Android 项目的 jniLibs 目录。通常,你会将这些库文件放在以下目录结构中:
css
复制代码
app/
├── src/
│   └── main/
│       └── jniLibs/
│           ├── arm64-v8a/
│           │   ├── libcrypto.so
│           │   └── libssl.so
  1. 在你的 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}
)
  1. 在 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 源代码中包含了大量的测试代码和工具,它们在生成最终的库时并不是必须的。你可以通过一些配置选项来跳过这些测试代码的编译,从而减小生成的库的体积并加快编译速度。

禁用不必要的测试代码和工具的方法

  1. no-tests:跳过测试代码的编译。

    • OpenSSL 提供了 no-tests 选项,可以在配置时使用它来禁用所有的测试代码和相关的编译,从而避免编译测试程序。
  2. no-fuzz:禁用 fuzzing 测试代码。

    • OpenSSL 包含 fuzz 测试代码,尽管没有直接的 no-fuzz 选项,但 fuzz 相关代码一般可以通过配置 disable-fuzz-libfuzzer 或在 build.info 文件中手动排除(如前面提到的方法)。

修改配置命令

你可以尝试以下配置命令,将不必要的测试和工具都排除在外,仅编译需要的部分:

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"

配置参数解释:

参数解读

  1. ./Configure

    • 这是运行 OpenSSL 的配置脚本,用于设置编译环境和选项。
  2. android-arm

    • 指定目标平台为 Android 的 ARM 架构。对应于 armeabi-v7a
  3. no-comp: 禁用压缩功能(如 Zlib 支持),减小库的体积。

  4. no-ec:禁用椭圆曲线加密(Elliptic Curve Cryptography)相关的功能。

  5. no-dh:禁用 Diffie-Hellman(DH)密钥交换算法。

  6. no-dsa:禁用 DSA(数字签名算法)。

  7. no-rc4:禁用 RC4 加密算法。

  8. no-des:禁用 DES(数据加密标准)算法。

  9. no-ssl:禁用 SSL(安全套接层)协议支持。

  10. no-fips:禁用 FIPS(联邦信息处理标准)模块相关的功能。

  11. no-tests:禁用测试代码的编译,避免生成任何测试程序,减小构建体积。

  12. --prefix=$HOME/openssl-android-armv7:指定安装路径的前缀,将生成的库和头文件安装到 $HOME/openssl-android-armv7 目录下。

  13. --openssldir=$HOME/openssl-android-armv7:指定 OpenSSL 配置文件(如 openssl.cnf)的安装目录。

  14. CFLAGS="-DNDEBUG -O3"

    • CFLAGS 用于设置编译器的选项:

      • -DNDEBUG:禁用调试模式,意味着不会生成调试信息,有助于优化性能。
      • -O3:启用最高级别的优化,编译器会尽可能优化生成的代码。
  15. LDFLAGS="-Wl,--strip-all"

    • LDFLAGS 用于设置链接器的选项:

      • -Wl,--strip-all:指示链接器去掉所有符号表和调试信息,以减小生成的库的体积。

armeabi-v7ax86 的配置命令。它们的编译步骤和 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"

总结:

  1. android-arm 用于编译 armeabi-v7a
  2. android-x86 用于编译 x86
  3. 这两个架构的命令和 android-arm64 基本一致,只需根据不同的架构目标修改配置。

编译完成后,你可以运行以下命令以清理构建并开始编译:

bash
复制代码
make clean
make
make install

这样你就可以为这三个架构生成对应的 OpenSSL 库了。

总结:

通过禁用测试代码和不必要的加密功能,你可以显著减少 OpenSSL 编译的内容。no-tests 选项特别有用,可以直接跳过所有的测试代码编译。如果有其他需要调整的模块,也可以继续通过类似的 no- 选项来剔除。