在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 行。
相关推荐
零涂毕业设计3 分钟前
毕业设计模块开发-OLED显示屏(IIC协议0.96寸)STM32 ESP32 FPGA Linux驱动免费分享
linux·stm32·单片机·嵌入式·esp32·fpga·oled
tedcloud12314 分钟前
OmniRoute怎么部署?开源AI模型路由平台Linux部署教程
linux·服务器·人工智能·开源·音视频
SakitamaX31 分钟前
LVS(Linux Virtual Server)概念详解
linux·运维·lvs
小张同学a.40 分钟前
Linux系统管理
linux·运维
阿龙的工作记录1 小时前
深入理解Linux设备驱动模型
linux·嵌入式硬件·工作记录
代码村新手1 小时前
Linux的基本指令
linux·运维·服务器
码农coding3 小时前
android 12 中的VSYNC的请求
android
阿pin3 小时前
Android随笔-Activity
android·activity
撩得Android一次心动4 小时前
Linux编程笔记3【个人用】
linux·笔记
OpenPomeloxCommunity4 小时前
3. Linux 同步机制之 spinlock 设计与实现(一):通用层
linux