鸿蒙PC三方库测试验证HPKCHECK 深度解读
OpenHarmony生态中的三方库适配面临一个关键挑战:如何确保交叉编译的产物能在真实设备上正确运行?HPKCHECK作为质量守门人,通过设备端测试彻底解决了这一痛点。本文将深入解析HPKCHECK的运行机制与编写规范,揭秘华为在开源生态建设中的工程实践智慧。

在 OpenHarmony 三方库适配中,HPKBUILD 负责把源码编译成产物,HPKCHECK 负责验证产物是否真的能用。
你可能会想:编译没报错不就行了?问题是,交叉编译出的 ARM 可执行文件无法在 x86 开发机上运行,你根本不知道它编译出来能不能正常工作。HPKCHECK 就是把测试程序推到真实 OpenHarmony 设备上执行,确保功能正确。
这篇文章把 HPKCHECK 的结构、执行流程、编写方法讲清楚。
HPKCHECK 文件内容
SHA 库的 HPKCHECK 内容如下:
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the “License”);
# …
# Contributor: huangminzhong <huangminzhong2@huawei.com>
# Maintainer: huangminzhong <huangminzhong2@huawei.com>
source HPKBUILD > /dev/null 2>&1
logfile=${LYCIUM_THIRDPARTY_ROOT}/${pkgname}/${pkgname}_${ARCH}_${OHOS_SDK_VER}_test.log
openharmonycheck() {
cd$builddir/$ARCH-build
ctest > ${logfile} 2>&1
res=$?
cd$OLDPWD
return$res
}
只有三个有效部分,下面逐个拆解。
逐部分解读
1. source HPKBUILD — 加载构建配置
source HPKBUILD > /dev/null 2>&1
通俗理解:把 HPKBUILD 里的变量和函数”搬”过来,这样 HPKCHECK 就能知道包名、构建目录等信息。
- source:在当前 Shell 环境中执行文件(不是启动子进程)
- >; /dev/null 2>&1:静默执行,不输出 HPKBUILD 的内容
加载后可用的关键变量:

2. logfile — 测试日志路径
logfile=${LYCIUM_THIRDPARTY_ROOT}/${pkgname}/${pkgname}_${ARCH}_${OHOS_SDK_VER}_test.log
通俗理解:定义测试日志文件的位置和名称。
展开后类似:thirdparty/sha/sha_arm64-v8a_10_test.log
日志文件名包含三个关键信息:
- sha:哪个库
- arm64-v8a:哪个架构
- 10:哪个 SDK 版本
这样不同配置的测试结果不会混在一起。
3. openharmonycheck() — 核心测试函数
openharmonycheck() {
cd $builddir/$ARCH-build
ctest > ${logfile} 2>&1
res=$?
cd $OLDPWD
return $res
}
通俗理解:进入构建目录,运行 CTest,记录结果,返回原目录。

CTest 会执行什么? 由 CMakeLists.txt 中的 add_test() 定义:
enable_testing()
add_test(NAME test_hmac COMMAND hmac)
add_test(NAME test_pwd2key COMMAND pwd2key)
add_test(NAME test_sha COMMAND sha_test)
三个测试用例分别验证 HMAC、密钥派生和 SHA 算法的正确性。
为什么需要单独的 HPKCHECK?
HPKBUILD 中的 check() 为什么不够?
HPKBUILD 里确实有个 check() 函数:
check() {
echo “The test must be on an OpenHarmony device!”
# ctest
}
但 ctest 被注释掉了,因为交叉编译环境无法运行测试:

HPKCHECK 的设计就是为了在真实设备上执行测试,而不是在开发机上。
完整的测试生命周期
开发机上:
HPKBUILD prepare() → build() → package() → archive()
(编译完成,但无法运行测试)
OpenHarmony 设备上:
HPKCHECK openharmonycheck()
(部署产物,运行测试,收集结果)
执行流程详解
HPKCHECK 通过 test.sh 脚本触发执行:
cd lycium && ./test.sh sha
完整执行流程
./test.sh sha
│
├─ 1. 设置环境变量(LYCIUM_ROOT、LYCIUM_THIRDPARTY_ROOT、OHOS_SDK_VER)
│
├─ 2. checktestenv():检查 cmake/make/ctest/perl 是否存在
│
├─ 3. getcpuarchitecture():检测 CPU 架构(arm64-v8a 或 armeabi-v7a)
│
├─ 4. setloaddynamiclibrarypath():设置 LD_LIBRARY_PATH
│
├─ 5. 查找 sha 库目录
│
└─ 6. checkhpk():遍历测试
│
├─ 进入 thirdparty/sha/
├─ source ./HPKCHECK
│ ├─ source HPKBUILD(加载变量)
│ ├─ 设置 logfile
│ └─ 定义 openharmonycheck()
│
├─ 检查是否有 checkprepare()(可选的测试前准备)
│
├─ 调用 openharmonycheck()
│ ├─ cd$builddir/$ARCH-build
│ ├─ ctest > ${logfile} 2>&1
│ ├─ res=$?
│ └─ cd$OLDPWD
│
├─ 判断结果:成功 → successlibs / 失败 → failedlibs
│
└─ 收集日志到 LOG_PATH
执行前提条件
- 已编译:先在开发机上执行 ./build.sh sha
- 已部署:将编译产物推送到 OpenHarmony 设备
- 工具就绪:设备上有 cmake、make、ctest、perl(可通过 CItools 部署)
规范写法与模板
标准 HPKCHECK 模板
# Copyright (c) 2023 Huawei Device Co., Ltd.
# Licensed under the Apache License, Version 2.0 (the “License”);
# …
source HPKBUILD > /dev/null 2>&1
logfile=${LYCIUM_THIRDPARTY_ROOT}/${pkgname}/${pkgname}_${ARCH}_${OHOS_SDK_VER}_test.log
# 可选:测试前的准备工作
checkprepare() {
return 0
}
# 必需:在 OpenHarmony 设备上执行测试
openharmonycheck() {
cd$builddir/$ARCH-build
ctest > ${logfile} 2>&1
res=$?
cd$OLDPWD
return$res
}
不同测试框架的写法

常见问题
Q1:测试必须在 OpenHarmony 设备上运行吗?
是的。 交叉编译出的 ARM 可执行文件无法在 x86 开发机上运行。如果开发机也是 ARM 架构的鸿蒙 PC,则可以直接运行。
Q2:如何部署测试工具到设备?
cd lycium/CItools && ./env_build.sh
这会把 cmake、make、ctest 等工具部署到 OpenHarmony 设备上。
Q3:测试失败如何调试?
- 查看日志文件:cat ${logfile}
- 检查设备上是否安装了所有依赖库
- 确认 LD_LIBRARY_PATH 设置正确
- 手动在设备上运行测试程序
Q4:如果三方库没有测试用例怎么办?
- 编写简单的测试程序验证基本功能
- 在 HPKCHECK 中跳过测试,但要在文档中说明原因
- 向上游项目贡献测试用例
Q5:checkprepare() 什么时候需要?
当测试前需要做额外准备时,比如:
- 创建测试数据文件
- 设置特殊的环境变量
- 启动依赖的服务
对于 SHA 这种简单库,不需要 checkprepare()。
与其他文件的关系
HPKCHECK
│
├─ source HPKBUILD ← 加载构建变量
│
├─ ctest ← 执行 CMakeLists.txt 中定义的测试
│
└─ test.sh ← 被 test.sh 调用
总结
HPKCHECK 是 OpenHarmony 三方库质量把关的关键文件:

核心要点:
- HPKCHECK 必须在 OpenHarmony 设备上执行,因为交叉编译的产物无法在开发机运行
- openharmonycheck() 是必须定义的函数,由 test.sh 调用
- checkprepare() 是可选的测试前准备函数
- 测试结果通过返回码传递:0 表示成功,非 0 表示失败
编译通过只是第一步,测试通过才是真正的成功。
本文由人人都是产品经理作者【nutpi】,微信公众号:【nutpi】,原创/授权 发布于人人都是产品经理,未经许可,禁止转载。
题图来自Unsplash,基于 CC0 协议
- 目前还没评论,等你发挥!

起点课堂会员权益



