导语:本文是腾讯端服务 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++三方库适配方面面临着独特的挑战:
- 编译方式多样化:开源C/C++库的构建方式包括cmake、configure、make等多种方式
- 架构支持需求:需要同时支持armeabi-v7a、arm64-v8a、x86_64等主流架构
- 工具链差异:OpenHarmony使用LLVM工具链,与传统的GCC工具链存在差异
- 运行时环境:OpenHarmony的运行时环境与Linux、Android等系统存在差异
tpc_c_cplusplus项目定位
tpc_c_cplusplus是OpenHarmony三方库适配的重要仓库,主要功能包括:
- 三方库适配脚本管理:存放已适配OpenHarmony的C/C++三方库的编译配置
- 技术文档沉淀:提供三方库适配指导文档和最佳实践
- 工具链支持:提供交叉编译框架lycium和相关工具
lycium框架
lycium是OpenHarmony三方库适配的核心框架,它是一个基于shell脚本的自动化交叉编译工具链。本文档将深入分析lycium框架的架构设计、工作原理和技术特点,帮助开发者更好地理解和使用这个框架。
lycium 解决的问题
- 编译方式多样化:开源C/C++库使用不同的构建系统(cmake、configure、make等),lycium 通过HPKBUILD配置文件统一管理这些构建方式。
- 架构支持复杂:需要同时支持armeabi-v7a、arm64-v8a、x86_64等多种架构
- 工具链差异:OpenHarmony使用LLVM工具链,与传统的GCC工具链存在差异
- 依赖管理复杂:三方库之间存在复杂的依赖关系
- 自动化构建:一键完成源码下载、交叉编译、产物打包
- 测试验证:提供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框架构建
↓
多架构二进制产物
关键技术组件
- OpenHarmony SDK:提供LLVM交叉编译工具链
- lycium Buildtools:补充交叉编译工具包
- HPKBUILD配置:定义编译参数和依赖关系
- 自动化脚本:实现编译、测试、打包全流程
编译实践总结
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库的编译实践,我们成功验证了:
- 技术可行性:lycium框架能够有效支持C/C++三方库的交叉编译
- 多架构支持:成功编译出支持多种架构的库文件
- 质量保证:通过测试验证确保库的功能完整性
- 工具成熟度:编译工具链和框架已经相对成熟