在Ubuntu系统上为Android交叉编译OpenSSL

在Ubuntu系统上为Android交叉编译OpenSSL(以OpenSSL 3.5.7为例)需要配置好Android NDK环境,并使用OpenSSL自带的配置脚本进行编译。

选取OpenSSL版本,可以在官网查看:https://openssl-library.org/source/,建议选择带有LTS标识的版本,为长期支持版。

在windows系统上配置Ubuntu系统虚拟机步骤详见上一篇文章,本文不再赘述。

以下是具体的步骤和示例脚本。

1. 准备工作

首先,更新Ubuntu系统的软件包列表并安装必要的构建工具:

bash 复制代码
sudo apt update
sudo apt install -y build-essential wget tar unzip make clang

2. 下载并配置 Android NDK

OpenSSL的交叉编译需要用到Android NDK。建议使用稳定版本(例如 NDK r25c 或 r26b)。

1. 下载 NDK(以 r25c 为例):

bash 复制代码
cd ~
wget https://dl.google.com/android/repository/android-ndk-r25c-linux.zip

2. 解压 NDK:

bash 复制代码
unzip android-ndk-r25c-linux.zip

3. 设置环境变量(你可以将其记录在临时变量中,或者写入 ~/.bashrc):

bash 复制代码
export ANDROID_NDK_HOME=$HOME/android-ndk-r25c
export ANDROID_NDK_ROOT=$ANDROID_NDK_HOME
export PATH=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH

永久写入环境变量具体操作步骤如下:

步骤 1:使用 nano 打开 ~/.bashrc 文件

在终端中输入以下命令:

bash 复制代码
nano ~/.bashrc
步骤 2:将环境变量添加到文件末尾

使用键盘上的 下方向键 一直滑到文件的最底部,然后在文件的最末尾,粘贴以下内容:

bash 复制代码
# Android NDK environment variables
export ANDROID_NDK_HOME=$HOME/android-ndk-r25c
export ANDROID_NDK_ROOT=$ANDROID_NDK_HOME
export PATH=$ANDROID_NDK_HOME/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH
步骤 3:保存并退出
  1. Ctrl + O 保存。
  2. Enter 确认文件名。
  3. Ctrl + X 退出 nano 编辑器。
步骤 4:使配置立即生效

在当前终端运行以下命令,使刚刚修改的配置立即生效(不需要重启电脑或重新打开终端):

bash 复制代码
source ~/.bashrc
验证是否成功

你可以运行以下命令来验证环境变量是否已正确配置:

bash 复制代码
echo $ANDROID_NDK_HOME

如果终端正确输出了 /home/你的用户名/android-ndk-r25c(或者你的实际 NDK 路径),说明配置已经永久生效。今后每次你打开新的终端窗口,这些变量都会自动加载。

3. 下载 OpenSSL 源码

本文以 OpenSSL 3.5.7 (长期支持版本 LTS) 为例。

bash 复制代码
cd ~
wget https://www.openssl.org/source/openssl-3.5.7.tar.gz
tar -zxvf openssl-3.5.7.tar.gz
cd openssl-3.5.7

4. 编写编译脚本

由于Android有不同的架构(如 arm64-v8a, armeabi-v7a, x86_64, x86),编写一个自动化脚本可以方便地为这些架构生成预编译库。

openssl-3.5.7 目录下创建一个名为 build_android.sh 的脚本:

bash 复制代码
nano build_android.sh

将以下内容复制到脚本中:

bash 复制代码
#!/bin/bash

# 1. 显式指定你的 NDK 路径(请确保该路径与你实际解压的 NDK 路径一致)
export ANDROID_NDK_ROOT=$HOME/android-ndk-r25c
export ANDROID_NDK_HOME=$ANDROID_NDK_ROOT

# 检查 NDK 路径是否存在
if [ ! -d "$ANDROID_NDK_ROOT" ]; then
    echo "Error: NDK directory not found at $ANDROID_NDK_ROOT"
    echo "Please check your NDK path in this script."
    exit 1
fi

# 定义支持的架构和对应的OpenSSL配置名称
ARCHS=(
    "arm64-v8a" "android-arm64" "21"
    "armeabi-v7a" "android-arm" "21"
    "x86_64" "android-x86_64" "21"
    "x86" "android-x86" "21"
)

# 获取当前工作目录
SRC_DIR=$(pwd)
# 定义输出目录
OUTPUT_DIR="${SRC_DIR}/android_build"

# 将 NDK 工具链加入 PATH
export PATH=$ANDROID_NDK_ROOT/toolchains/llvm/prebuilt/linux-x86_64/bin:$PATH

# 循环编译各个架构
for ((i=0; i<${#ARCHS[@]}; i+=3)); do
    ABI=${ARCHS[i]}
    TARGET=${ARCHS[i+1]}
    API=${ARCHS[i+2]}

    echo "=========================================="
    echo "Building OpenSSL for ${ABI} (API ${API})..."
    echo "=========================================="

    # 清理之前的编译残留
    make clean 2>/dev/null

    # 创建输出路径
    PREFIX="${OUTPUT_DIR}/${ABI}"
    mkdir -p "${PREFIX}"

    # 配置 OpenSSL
    ./Configure ${TARGET} \
        -D__ANDROID_API__=${API} \
        --prefix="${PREFIX}" \
        --openssldir="${PREFIX}/ssl" \
        no-shared \
        no-tests

    # 编译并安装
    make -j$(nproc)
    make install_sw
done

echo "Build completed. Outputs are located in: ${OUTPUT_DIR}"

5. 执行编译

1. 给脚本赋予执行权限:

bash 复制代码
chmod +x build_android.sh

2. 运行脚本:

bash 复制代码
./build_android.sh

6. 查看编译结果

编译完成后,预编译的文件会输出在 openssl-3.5.7/android_build 目录下。目录结构大致如下:

text 复制代码
android_build/
├── arm64-v8a
│   ├── bin
│   ├── include
│   │   └── openssl
│   └── lib
│       ├── libcrypto.a
│       └── libssl.a
├── armeabi-v7a
│   ...
  • include/openssl:存放头文件,在 Android 项目(如 CMake)中配置 target_include_directories 时会用到。
  • lib:存放生成的静态库 libcrypto.alibssl.a。如果在脚本配置中去掉了 no-shared,此处还会生成 libcrypto.solibssl.so

验证生成的文件

你可以运行以下命令来查看生成的预编译库文件结构:

bash 复制代码
ls -l /home/openclaw/openssl-3.5.7/android_build

你应该会看到生成了 4 个对应 Android 架构的文件夹。接着,你可以检查具体某个架构下的库文件是否存在(例如 arm64-v8a):

bash 复制代码
ls -l /home/openclaw/openssl-3.5.7/android_build/arm64-v8a/lib/

如果在这个 lib 文件夹下看到了 libcrypto.alibssl.a,说明这些就是你所需要的 Android 预编译静态库。

注意事项

  1. API Level : 脚本中设置的 __ANDROID_API__21。如果你的应用需要支持更旧的设备,或者需要使用更新的系统特性,可以根据实际需求调整该值(例如 2426 等)。
  2. 动态库与静态库 :
    • 默认脚本中开启了 no-shared,这会生成静态库 (.a)。静态库便于打包,不易产生动态链接冲突。
    • 如果需要动态库 (.so),请从脚本的 ./Configure 命令中移除 no-shared 行。
相关推荐
nannan85861 小时前
android 性能+AI 日志库-StatLog
android
长孙豪翔1 小时前
引发事件的问题
java·linux·数据库
小张成长计划..1 小时前
【Linux】7:第一个系统程序-进度条
linux·运维·服务器
xuankuxiaoyao2 小时前
Zygisk-LSPosed 模块完整作用说明
android
枳实-叶2 小时前
【Linux驱动开发】第23天:spi_driver 的 probe / remove 函数实现规范
linux·驱动开发·c#
李子琪。2 小时前
云计算虚拟化技术全解析:从理论到实践
linux·centos·云计算
wuminyu2 小时前
markword在高并发场景下变化剖析
java·linux·c语言·jvm·c++
Cloud_Shy6182 小时前
Linux 用户管理知识与应用实践(二:用户相关命令与示例)
linux·运维·服务器·测试用例
YXL1111YXL2 小时前
ViewModel 底层原理
android