Skip to main content

OpenHarmony三方库交叉编译实践总结

· 18 min read

导语:本文是腾讯端服务 Shiply 平台 C++ SDK 适配鸿蒙平台过程中,对依赖三方库在鸿蒙平台交叉编译的实践总结。Shiply 支持鸿蒙平台的远程配置、远程开关、远程资源、应用内更新提示、应用商店提审、应用尝鲜提审、企业签名包内部分发等诸多强大功能,欢迎联系 Shiply 客户经理 进行咨询

概述

本文档基于bzip2和OpenSSL库在OpenHarmony平台上的完整交叉编译实践,总结了使用lycium框架进行C/C++三方库交叉编译的经验和方法。通过本次实践,我们成功在macOS环境下为OpenHarmony 3.2 Release系统编译了bzip2和OpenSSL两个核心库,涵盖了armeabi-v7a、arm64-v8a和x86_64三种主流架构。

项目背景与技术生态

OpenHarmony三方库适配现状

OpenHarmony作为华为推出的开源分布式操作系统,在C/C++三方库适配方面面临着独特的挑战:

  1. 编译方式多样化:开源C/C++库的构建方式包括cmake、configure、make等多种方式
  2. 架构支持需求:需要同时支持armeabi-v7a、arm64-v8a、x86_64等主流架构
  3. 工具链差异:OpenHarmony使用LLVM工具链,与传统的GCC工具链存在差异
  4. 运行时环境:OpenHarmony的运行时环境与Linux、Android等系统存在差异

tpc_c_cplusplus项目定位

tpc_c_cplusplus是OpenHarmony三方库适配的重要仓库,主要功能包括:

  1. 三方库适配脚本管理:存放已适配OpenHarmony的C/C++三方库的编译配置
  2. 技术文档沉淀:提供三方库适配指导文档和最佳实践
  3. 工具链支持:提供交叉编译框架lycium和相关工具

lycium框架

lycium是OpenHarmony三方库适配的核心框架,它是一个基于shell脚本的自动化交叉编译工具链。本文档将深入分析lycium框架的架构设计、工作原理和技术特点,帮助开发者更好地理解和使用这个框架。

lycium 解决的问题

  1. 编译方式多样化:开源C/C++库使用不同的构建系统(cmake、configure、make等),lycium 通过HPKBUILD配置文件统一管理这些构建方式。
  2. 架构支持复杂:需要同时支持armeabi-v7a、arm64-v8a、x86_64等多种架构
  3. 工具链差异:OpenHarmony使用LLVM工具链,与传统的GCC工具链存在差异
  4. 依赖管理复杂:三方库之间存在复杂的依赖关系
  5. 自动化构建:一键完成源码下载、交叉编译、产物打包
  6. 测试验证:提供HPKCHECK脚本支持自动化测试

lycium 目录结构

lycium/
├── build.sh # 主构建脚本
├── test.sh # 测试脚本
├── script/ # 核心脚本目录
│ ├── build_hpk.sh # 单个库构建脚本
│ └── envset.sh # 环境变量设置脚本
├── template/ # 模板文件
│ ├── HPKBUILD # 构建配置模板
│ └── HPKCHECK # 测试配置模板
├── Buildtools/ # 构建工具
│ ├── toolchain.tar.gz # 交叉编译工具链
│ └── README.md # 工具说明
├── CItools/ # 持续集成工具
├── doc/ # 文档目录
├── usr/ # 编译产物目录
└── docker/ # Docker支持

lycium 架构层次

┌─────────────────────────────────────────────────────────┐
│ 用户接口层 │
│ build.sh (主构建脚本) test.sh (测试脚本) │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 业务逻辑层 │
│ 依赖解析 │ 构建调度 │ 环境管理 │ 错误处理 │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 构建执行层 │
│ build_hpk.sh │ envset.sh │ HPKBUILD │ HPKCHECK │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 工具链层 │
│ LLVM工具链 │ 交叉编译工具 │ 构建系统适配 │
└─────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────┐
│ 平台层 │
│ OpenHarmony SDK │ 操作系统 │ 硬件架构 │
└─────────────────────────────────────────────────────────┘

技术架构分析

交叉编译技术栈

macOS + DevEco Studio SDK

OHOS_SDK环境配置

LLVM交叉编译工具链

lycium框架构建

多架构二进制产物

关键技术组件

  1. OpenHarmony SDK:提供LLVM交叉编译工具链
  2. lycium Buildtools:补充交叉编译工具包
  3. HPKBUILD配置:定义编译参数和依赖关系
  4. 自动化脚本:实现编译、测试、打包全流程

编译实践总结

1. 编译环境准备

1.1 基本工具检查

首先检查系统是否安装了必需的基本编译工具:

# 检查基本编译工具
which gcc make pkg-config autoconf autoreconf automake

检查结果

  • ✅ gcc: /usr/bin/gcc
  • ✅ make: /usr/bin/make
  • ✅ pkg-config: /opt/homebrew/bin/pkg-config
  • ✅ autoconf: /opt/homebrew/bin/autoconf
  • ✅ autoreconf: /opt/homebrew/bin/autoreconf
  • ✅ automake: /opt/homebrew/bin/automake

缺少的工具可以使用 homebrew 进行安装

1.2 OHOS SDK环境配置

检查OHOS_SDK环境变量配置:

echo $OHOS_SDK

配置结果

  • ✅ OHOS_SDK: /Applications/DevEco-Studio.app/Contents/sdk/default/openharmony

1.3 交叉编译工具链检查

检查SDK中的交叉编译工具链:

ls -la $OHOS_SDK/native/llvm/bin/ | head -10

工具链文件

  • ✅ aarch64-unknown-linux-ohos-clang
  • ✅ aarch64-unknown-linux-ohos-clang++
  • ✅ armv7-unknown-linux-ohos-clang
  • ✅ armv7-unknown-linux-ohos-clang++
  • ✅ clang, clang-15
  • ✅ 其他LLVM工具

1.4 cmake版本检查

检查cmake版本是否满足要求(需要3.26+):

which cmake && cmake --version

检查结果

  • ✅ cmake路径: /opt/homebrew/bin/cmake
  • ✅ cmake版本: 3.31.6 (满足3.26+要求)

1.5 编译工具包配置

解压并配置lycium提供的交叉编译工具包:

# 进入Buildtools目录
cd lycium/Buildtools

# 检查工具包文件
ls -la lycium/Buildtools/
# 输出:
# -rw-r--r-- 1 mellow staff 2323 Dec 19 2023 README.md
# -rw-r--r-- 1 mellow staff 146 Dec 19 2023 SHA512SUM
# drwxr-xr-x@ 2 mellow staff 64 Aug 12 10:38 toolchain
# -rw-r--r-- 1 mellow staff 438 Aug 12 10:23 toolchain.tar.gz

# 解压工具包
tar -zxvf toolchain.tar.gz

# 拷贝编译工具到SDK目录
cp toolchain/* $OHOS_SDK/native/llvm/bin/

解压的工具文件

  • ✅ arm-linux-ohos-clang++
  • ✅ aarch64-linux-ohos-clang++
  • ✅ x86_64-linux-ohos-clang
  • ✅ aarch64-linux-ohos-clang
  • ✅ x86_64-linux-ohos-clang++
  • ✅ arm-linux-ohos-clang

2. bzip2库配置检查

2.1 库目录结构

检查bzip2库的配置文件和目录结构:

ls -la thirdparty/bzip2/

目录结构

thirdparty/bzip2/
├── docs/ # 文档目录
├── HPKBUILD # 构建脚本
├── HPKCHECK # 测试脚本
├── README_zh.md # 中文说明
├── README.OpenSource # 开源信息
├── SHA512SUM # 校验文件
└── 构建目录/ # 编译生成的目录

2.2 构建脚本分析

查看HPKBUILD构建脚本的关键配置:

cat thirdparty/bzip2/HPKBUILD

关键配置信息

  • 库名称: bzip2
  • 版本: 1_0_6
  • 支持架构: armeabi-v7a, arm64-v8a, x86_64
  • 构建方式: make
  • 编译工具: 使用OHOS SDK中的交叉编译工具链

3. bzip2编译执行过程

3.1 开始编译

在lycium目录下执行编译命令:

cd lycium
./build.sh bzip2

3.2 编译输出日志

Build OS Darwin
OHOS_SDK=/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony
CLANG_VERSION=15.0.4
x toolchain/
x toolchain/arm-linux-ohos-clang++
x toolchain/aarch64-linux-ohos-clang++
x toolchain/x86_64-linux-ohos-clang
x toolchain/aarch64-linux-ohos-clang
x toolchain/x86_64-linux-ohos-clang++
x toolchain/arm-linux-ohos-clang
cp: the -R and -r options may not be specified together
Start building bzip2 1_0_6!
Downloading bzip2-bzip2-1_0_6.zip
bzip2-bzip2-1_0_6.zip: OK
Compileing OpenHarmony armeabi-v7a bzip2 1_0_6 libs...
Compileing OpenHarmony arm64-v8a bzip2 1_0_6 libs...
Compileing OpenHarmony x86_64 bzip2 1_0_6 libs...
Build bzip2 1_0_6 end!
ALL JOBS DONE!!!

编译状态

  • ✅ 源码下载成功
  • ✅ 三个架构版本编译完成
  • ✅ 编译过程无错误

4. bzip2编译结果验证

4.1 生成文件结构检查

检查编译生成的库文件结构:

ls -la usr/bzip2/

生成目录结构

usr/bzip2/
├── arm64-v8a/ # 64位ARM架构
├── armeabi-v7a/ # 32位ARM架构
└── x86_64/ # x86_64架构

4.2 详细文件检查

检查arm64-v8a架构的生成文件:

ls -la usr/bzip2/arm64-v8a/

文件结构

arm64-v8a/
├── bin/ # 可执行文件目录
├── include/ # 头文件目录
├── lib/ # 库文件目录
└── man/ # 手册页目录

4.3 关键文件验证

生成文件

  • 静态库: libbz2.a (207,002 bytes)
  • 头文件: bzlib.h (6,245 bytes)

可执行文件(我们只集成静态库可以删掉可执行文件)

  • bzip2 (218,176 bytes) - 主要压缩工具
  • bunzip2 (218,176 bytes) - 解压工具
  • bzcat (218,176 bytes) - 查看压缩文件内容
  • bzip2recover (32,800 bytes) - 恢复损坏的压缩文件
  • ✅ 其他工具脚本: bzdiff, bzgrep, bzmore

5. OpenSSL库编译记录

5.1 OpenSSL库配置检查

检查OpenSSL库的配置文件和目录结构:

ls -la thirdparty/openssl/

目录结构

thirdparty/openssl/
├── docs/ # 文档目录
├── HPKBUILD # 构建脚本
├── HPKCHECK # 测试脚本
├── README_zh.md # 中文说明
├── README.OpenSource # 开源信息
├── SHA512SUM # 校验文件
├── openssl_oh_test.patch # 测试补丁文件
└── openssl-OpenSSL_1_1_1u/ # 源码目录
5.2 构建脚本分析

查看HPKBUILD构建脚本的关键配置:

cat thirdparty/openssl/HPKBUILD

关键配置信息

  • 库名称: openssl
  • 版本: OpenSSL_1_1_1u
  • 支持架构: armeabi-v7a, arm64-v8a, x86_64
  • 构建方式: configure (autotools)
  • 特殊配置: 使用patch文件修复测试问题

5.3 OpenSSL编译执行过程

在lycium目录下执行编译命令:

cd lycium
./build.sh openssl

5.4 编译输出日志

Build OS Darwin
OHOS_SDK=/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony
CLANG_VERSION=15.0.4
x toolchain/
x toolchain/arm-linux-ohos-clang++
x toolchain/aarch64-linux-ohos-clang++
x toolchain/x86_64-linux-ohos-clang
x toolchain/aarch64-linux-ohos-clang
x toolchain/x86_64-linux-ohos-clang++
x toolchain/arm-linux-ohos-clang
cp: the -R and -r options may not be specified together
Start building openssl OpenSSL_1_1_1u!
Downloading openssl-OpenSSL_1_1_1u.zip
openssl-OpenSSL_1_1_1u.zip: OK
openssl_oh_test.patch: OK
Compileing OpenHarmony armeabi-v7a openssl OpenSSL_1_1_1u libs...
patching file 'util/check-malloc-errs'
patching file 'util/find-doc-nits'
patching file 'util/find-unused-errs'
patching file 'util/openssl-format-source'
Compileing OpenHarmony arm64-v8a openssl OpenSSL_1_1_1u libs...
Compileing OpenHarmony x86_64 openssl OpenSSL_1_1_1u libs...
Build openssl OpenSSL_1_1_1u end!
ALL JOBS DONE!!!

编译状态

  • ✅ 源码下载成功
  • ✅ 测试补丁应用成功
  • ✅ 三个架构版本编译完成
  • ✅ 编译过程无错误

5.5 OpenSSL编译结果验证

生成目录结构

usr/openssl/
├── arm64-v8a/ # 64位ARM架构
├── armeabi-v7a/ # 32位ARM架构
└── x86_64/ # x86_64架构

文件结构

arm64-v8a/
├── bin/ # 可执行文件目录
├── include/ # 头文件目录
├── lib/ # 库文件目录
├── share/ # 共享文件目录
└── ssl/ # SSL配置文件目录

6. 编译结果总结

6.1 成功编译的库

bzip2库

  • 版本: 1_0_6
  • 架构: armeabi-v7a, arm64-v8a, x86_64
  • 主要文件: libbz2.a, bzlib.h, bzip2可执行文件

OpenSSL库

  • 版本: OpenSSL_1_1_1u
  • 架构: armeabi-v7a, arm64-v8a, x86_64
  • 主要文件: libcrypto.a, libssl.a, openssl头文件

技术难点与解决方案

1. 交叉编译工具链配置

问题:OpenHarmony使用LLVM工具链,需要正确配置交叉编译环境

解决方案

# 设置环境变量
export OHOS_SDK=/Applications/DevEco-Studio.app/Contents/sdk/default/openharmony

# 补充编译工具
cp lycium/Buildtools/toolchain/* $OHOS_SDK/native/llvm/bin/

2. 多架构编译支持

问题:需要同时支持多种CPU架构

解决方案

# HPKBUILD中配置多架构
archs=("armeabi-v7a" "arm64-v8a" "x86_64")

# 针对不同架构设置编译参数
if [ $ARCH == "armeabi-v7a" ]; then
cc=${OHOS_SDK}/native/llvm/bin/arm-linux-ohos-clang
host=linux-generic32
elif [ $ARCH == "arm64-v8a" ]; then
cc=${OHOS_SDK}/native/llvm/bin/aarch64-linux-ohos-clang
host=linux-aarch64
fi

3. 测试验证问题

问题:OpenSSL等库的测试用例在OpenHarmony环境下可能失败

解决方案

  • 应用测试补丁修复已知问题
  • 区分误判和真实错误
  • 避免使用dlopen等有问题的功能

4. 构建方式适配

问题:不同库使用不同的构建系统

解决方案

  • make方式:直接使用原生Makefile
  • configure方式:使用autotools配置
  • cmake方式:使用CMake构建系统

最佳实践总结

1. 环境准备最佳实践

# 1. 检查基础工具
which gcc make pkg-config autoconf autoreconf automake

# 2. 验证SDK配置
echo $OHOS_SDK

# 3. 检查cmake版本
cmake --version # 需要3.26+

# 4. 配置工具链
cd lycium/Buildtools
tar -zxvf toolchain.tar.gz
cp toolchain/* $OHOS_SDK/native/llvm/bin/

2. HPKBUILD配置最佳实践

# 基本信息配置
pkgname=your_library
pkgver=1.0.0
pkgdesc="Library description"
url="https://example.com"
archs=("armeabi-v7a" "arm64-v8a" "x86_64")
license=("MIT")
depends=()
makedepends=()

# 源码配置
source="https://example.com/your_library-1.0.0.tar.gz"
downloadpackage=true
autounpack=true
buildtools="make" # 或 "configure" 或 "cmake"

# 构建目录配置
builddir=your_library-1.0.0
packagename=$builddir.tar.gz

3. 编译流程最佳实践

# 1. 准备阶段
prepare() {
mkdir -p $builddir/$ARCH-build
# 设置架构相关环境变量
if [ $ARCH == "arm64-v8a" ]; then
setarm64ENV
fi
}

# 2. 构建阶段
build() {
cd $builddir/$ARCH-build
# 执行编译命令
$MAKE
cd $OLDPWD
}

# 3. 打包阶段
package() {
cd $builddir/$ARCH-build
$MAKE install
cd $OLDPWD
}

4. 测试验证最佳实践

# 1. 编写测试脚本
check() {
cd $builddir/$ARCH-build
# 运行测试用例
$MAKE test
cd $OLDPWD
}

# 2. 在设备上验证
./test.sh your_library

应用集成指南

1. 库文件集成

# 拷贝库文件到项目
cp -r lycium/usr/your_library/ your_project/cpp/thirdparty/

2. CMakeLists.txt配置

# 静态库链接
target_link_libraries(entry PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/your_library/${OHOS_ARCH}/lib/libyour_library.a)

# 头文件路径
target_include_directories(entry PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/your_library/${OHOS_ARCH}/include)

3. 动态库集成

# 动态库需要拷贝到libs目录
cp your_library.so your_project/entry/libs/${OHOS_ARCH}/

常见问题与解决方案

1. 编译失败问题

问题:编译过程中出现错误

解决方案

  • 检查OHOS_SDK环境变量设置
  • 验证交叉编译工具链配置
  • 确认源码下载是否成功
  • 检查磁盘空间是否充足

2. 架构不匹配问题

问题:库文件架构与目标平台不匹配

解决方案

  • 确认使用正确的架构版本(arm64-v8a或armeabi-v7a)
  • 检查HPKBUILD中的archs配置
  • 验证编译产物架构

3. 依赖缺失问题

问题:库依赖其他三方库

解决方案

  • 在HPKBUILD中配置depends字段
  • 确保依赖库先编译完成
  • 检查依赖库的架构支持

4. 测试失败问题

问题:测试用例在OpenHarmony环境下失败

解决方案

  • 应用必要的测试补丁
  • 区分误判和真实错误
  • 避免使用不兼容的功能

总结

通过本次bzip2和OpenSSL库的编译实践,我们成功验证了:

  1. 技术可行性:lycium框架能够有效支持C/C++三方库的交叉编译
  2. 多架构支持:成功编译出支持多种架构的库文件
  3. 质量保证:通过测试验证确保库的功能完整性
  4. 工具成熟度:编译工具链和框架已经相对成熟

参考资料