鸿蒙三方库适配读懂 `HPKBUILD`:lycium 怎么知道「下载谁、怎么编、装到哪」?

鸿蒙三方库适配读懂 HPKBUILD:lycium 怎么知道「下载谁、怎么编、装到哪」?

欢迎大家加入开源鸿蒙跨平台开发者社区

前言

在 OpenHarmony 三方库 lycium 体系里,每个库目录下会有一个 HPKBUILD 文件。你可以把它理解成 「构建说明书」 :用 Shell 变量 描述 包是谁、版本多少、从哪下载 ,再用若干个 函数 描述 解压后要改什么、怎么交叉编译、产物拷贝到哪、要不要打 HNP 包

本文件由 lycium/script/build_hpk.sh 通过 source HPKBUILD 读入并调用其中的函数;你在 lycium 根目录 执行 ./build.sh AES 时,脚本会进入 thirdparty/AES (或你工程里对应路径),在该目录下 sourceHPKBUILD 并执行 build_hpk.sh 里的主流程。

本文在 变量(字段)各函数职责 之外,补充:脚本真实调用顺序传入 build() 的 CMake 参数从哪来常见目录长什么样排错与升级时要改哪些地方 ,方便对照仓库里的 HPKBUILD 原文 阅读。


工作目录与路径约定(读脚本前先建立空间感)

概念 本仓库典型值 说明
库根目录(PKGBUILD_ROOT .../thirdparty/AES build_hpk.sh 所在目录;PWD 在执行 prepare/build/package 的多数时刻会 cdbuilddir 再返回,但 archive() 里复制 hnp.json 用的是 ${PWD}/hnp.json ,要求 在库根执行(与 lycium 设计一致)。
LYCIUM_ROOT .../lycium lycium/build.sh 里导出;安装产物$LYCIUM_ROOT/usr/AES/<ARCH>/archive 输出$LYCIUM_ROOT/output/<ARCH>/
builddir tiny-AES-c-1.0.0 packagename 解压结果一致,位于 库根下 (与 HPKBUILD 同级)。
CMake 构建目录 tiny-AES-c-1.0.0/arm64-v8a-build -B"$ARCH-build" 相对 源码根HPKCHECK 必须 cd "${builddir}/${ARCH}-build",与此严格一致。

引号习惯: builddir 含连字符 ,凡 cdrm -rf、路径拼接 建议写 "$builddir""${PWD}/$builddir",避免被 shell 拆成多个词(社区 HPK 规范里这是常见坑)。


上半部分:变量(字段)一览

下面这些不是 JSON 字段,而是 Bash 变量 ,供 build_hpk.sh 使用。

变量名 本仓库取值 通俗含义
pkgname AES 包 / 库在 lycium 里的名字 ,必须与 thirdparty/ 下文件夹名 一致,否则 ./build.sh AES 找不到。同时决定安装根路径 $LYCIUM_ROOT/usr/AES/
pkgver 1.0.0 上游源码版本号 ,与 tag v1.0.0builddirpackagenamehnp.jsonversion 等应对齐。
pkgrel 0 适配脚本发布号(第几次打 HPK 包),与上游版本独立;只改适配脚本未改上游时,通常会递增它。
pkgdesc 英文短描述 一句话说明这个包是干什么的,给人读和维护用。
url GitHub 上游地址 上游主页,溯源、文档链接用。
archs armeabi-v7aarm64-v8a 要编哪些 CPU 架构 ;数组里 每个架构 都会完整跑一遍 prepare → build → package → archive(若有)→ check(若开启)
license Unlicense 上游许可证 (tiny-AES-c);本仓库另有 MIT 的适配文件,见 LICENSE / README.OpenSource
depends 空数组 运行时依赖的其他 HPK 包名 (目录名)。本库无。若有依赖,./build.sh A B要先写被依赖的 B ,否则 A 会因 builddepends 返回 101 而推迟构建。
makedepends 空数组 本机构建前要用到的可执行命令名 (如 python3);脚本会对每个元素 which,找不到就退出。本库依赖 cmake/make 由 lycium 全局检查,此处可空。
source codeload 的 tar.gz URL 源码下载地址 ;用 ${pkgver} 拼出版本。codeload.github.com 在 macOS wget 下往往比 github.com/.../archive/refs/tags/... 更稳。
downloadpackage true 是否自动下载 packagename ;设为 false 时需自行把源码放到约定位置并在 prepare 里处理。
autounpack true 是否自动解压false 时在 prepare 里自己 tar/unzip
buildtools cmake 构建方式 。为 cmake (或空,默认 cmake)时,build_hpk.shbuild 调用 cmakedependpath $ARCH ,拼出传给 build "$@"buildargs
builddir tiny-AES-c-${pkgver} 解压后的源码根目录名含连字符cd 务必加引号
packagename ${builddir}.tar.gz 磁盘上的源码压缩包文件名wget -O 的目标名,且应与 SHA512SUM 第二列一致。

第一行注释 # Maintainer: ... 仅说明维护关系,不参与逻辑。


SHA512SUM 与下载:和 HPKBUILD 怎么配合?

build_hpk.shdownload $source $packagename 之后:若库目录下存在 SHA512SUM 文件,会执行 sha512sum -c SHA512SUM

  • 作用 :防止下载损坏或被劫持的 tarball,与 source URL 变更后内容是否仍一致。
  • 你要做的 :更换 pkgver / source / packagename 后,用新包算一遍 SHA512 ,更新 SHA512SUM 里对应行。
  • 校验失败 :脚本会提示失败并退出,不会自动删包,方便你比对后决定是重下还是修正哈希。

下载日志在库根 download.logwget-o 输出),体积异常或 404 时可打开查看。


build_hpk.sh 里真实发生的事(按时间顺序)

下面与 lycium/script/build_hpk.shmain → cleanhpk → builpackage 逻辑对应,便于你把 变量函数 对上号。
否 exit 101







cleanhpk: cleanbuild + 可选删坏包
builpackage: builddepends 检查 depends
依赖齐全?
写入待编译依赖列表
download source -> packagename
存在 SHA512SUM?
sha512sum -c
unpack packagename
for arch in archs
ARCH=arch 设置 buildlog
prepare
cmakedependpath 拼 buildargs
build buildargs
package
定义了 archive?
archive
跳过
LYCIUM_BUILD_CHECK=true?
check
跳过 check
recordbuildlibs

要点摘要:

  1. cleanbuild() 会先删掉 $builddir$packagename,保证本次是干净树(若你本地想保留已下载的 tar,需知每次 full build 会清掉,与 lycium 一致)。
  2. depends :在 builpackage 入口builddepends 与「已编译列表」比对;缺依赖时 exit 101不会进入 prepare
  3. prepare 在每个 arch 循环里都执行一次 :本库 prepare 幂等 (整文件覆盖 CMakeLists.txt ),重复执行不会叠加坏内容;若某库用 cat >> 追加 CMake,则要自己 grep -q 做幂等(别的库的坑,此处顺带提醒)。
  4. build $buildargs :这里的 $buildargs 来自 cmakedependpath ,不是 HPKBUILD 里手写的HPKBUILDbuild() 里用 "$@" 接住。
  5. declare -F archive :只有 HPKBUILD 里定义了 archive 函数 才会调用;本仓库
  6. check :仅当 LYCIUM_BUILD_CHECKtrue 时执行;在 Darwinlycium/build.sh 常把 LYCIUM_BUILD_CHECK 设为 false ,则 不会跑 check() ,这是环境行为,不是 HPKBUILD 写错
  7. recordbuildlibs :往 $LYCIUM_ROOT/usr/hpk_build.csv 记一笔,供依赖解析与跳过已构建使用。

传给 build() 的 CMake 参数(cmakedependpath 摘要)

buildtools="cmake" 时,cmakedependpath $ARCH 会构造 buildargs,核心包括(具体以你 SDK 路径为准):

片段 作用
-DCMAKE_TOOLCHAIN_FILE=${OHOS_SDK}/native/build/cmake/ohos.toolchain.cmake 指定 OHOS 交叉编译工具链
-DCMAKE_INSTALL_PREFIX=$LYCIUM_ROOT/usr/$pkgname/$ARCH/ CMake 语义上的安装前缀;本库 package()手动 cp ,与此前缀 对齐同一套目录结构
-G "Unix Makefiles" 生成 Makefile ,后续 $MAKE -C $ARCH-build
-DOHOS_ARCH=$ARCH 目标架构,与 armeabi-v7a / arm64-v8a 对应。
-DCMAKE_BUILD_TYPE=Release Release、跳过 RPATH 等,减少设备上多余依赖。

本库 depends=() ,因此 不会 追加 -DCMAKE_FIND_ROOT_PATH=... (有依赖时才会把其它库的 usr/<dep>/$ARCH 拼进搜索路径)。

build() 又额外传入 -B"$ARCH-build" -S. ,与 buildargs 合并后交给 ${OHOS_SDK}/native/build-tools/cmake/bin/cmake ,并把 stdout/stderr 追加到 buildlog


关键函数是干什么的?

prepare():解压后、编译前的「准备工作」

什么时候调? archs 循环里,每个 ARCHbuild() 之前都会执行(见上一节流程图)。

本库做了两件事:

  1. 统一换行符

    aes.caes.htest.csed 's/\r$//' ,去掉可能的 Windows CRLF 。在 HPK 实践里,CRLF 会导致 source HPKBUILD 报错prepare 里 heredoc 异常编译器解析奇怪,属于高频坑。

  2. 重写 CMakeLists.txtcat <<'EOF'

    • 上游 v1.0.0 自带 CMake 将 target_include_directories 指到不存在的 tiny-AES-c/ 子目录,交叉编译会 找不到 aes.h
    • 本适配直接写入完整 CMake,实现:静态库 tiny-aeslibtiny-aes.atiny_aes_testCTest 用例名 tiny_aes_upstream_tests 、以及与标准布局一致的 install(...) (与 package() 手动拷贝 语义对齐)。

为何用单引号 heredoc <<'EOF' 防止 shell 提前展开 ${CMAKE_CURRENT_SOURCE_DIR} 等,应原样交给 CMake。

最后 cd "$OLDPWD" 回到进入 prepare 前的目录(库根)


build():用 OHOS 工具链跑 CMake + Make

  1. cd "$builddir"
  2. cmake ... "$@" -B"$ARCH-build" -S. >> "$buildlog" 2>&1
  3. 失败则 return ;成功则 $MAKE -C "$ARCH-build" ,同样追加到 buildlog
  4. cd "$OLDPWD" ,返回 make 退出码

buildlog 文件名 形如 AES-1.0.0-arm64-v8a-lycium_build.log ,在 库根 ;cmake 详细报错、未找到编译器、链接失败等 优先打开此文件


package():把编好的东西摆到 lycium 标准「安装树」

$builddir 下执行:

目标路径 内容
$LYCIUM_ROOT/usr/AES/$ARCH/lib/ libtiny-aes.a
.../include/ aes.h
.../bin/ tiny_aes_test(若生成)

应用链接:-I$LYCIUM_ROOT/usr/AES/$ARCH/include -L.../lib -ltiny-aes (静态库目标名为 tiny-aes ,产物文件 libtiny-aes.a)。


archive():打发布包 + 可选 HNP

  1. mkdir -p "${LYCIUM_ROOT}/output/$ARCH"
  2. cp "${PWD}/hnp.json"usr/AES/$ARCH/ (与 lib 同级)。
  3. usr/AES/$ARCHtar -zvcf .../${pkgname}_${pkgver}.tar.gz * ,即 AES_1.0.0.tar.gz ,落在 lycium/output/$ARCH/
  4. hnpcli pack :若可执行则调用;否则 buildlog不使整次构建失败

注意: output 路径相对 LYCIUM_ROOT(lycium 根) ;若你在 独立 git 仓库 thirdparty/AES 里另外维护 output/ 拷贝,属于 发布策略 ,与 lycium 默认 lycium/output 不是同一路径,文档里不要混为一谈。


check():仅提示,不跑测试

打印说明:交叉编译出的测试二进制不能在宿主机上跑 ;设备上 ctest / ./tiny_aes_test
HPKCHECK + test.sh 才是设备侧自动化入口。


cleanbuild():清理,方便下次干净构建

rm -rf "${PWD}/$builddir"rm -f "${PWD}/$packagename"
cleanhpk 还会在校验失败时 删掉坏的 packagename (见 build_hpk.sh ),与 cleanbuild 略有叠加,都是为 可重复构建 服务。


上游 CMake 与本适配的差异(一眼对照)

项目 上游 tiny-AES-c v1.0.0(节选问题) prepare() 写入的 CMake
include 路径 PRIVATE tiny-AES-c/(解压后不存在) PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}
库类型 / 测试 add_library,无测试目标 STATIC + tiny_aes_test + CTest
安装 无完整 install 语义 install(TARGETS/FILES ...)package() 对齐

构建成功后,目录「长什么样」(示意)

库根 thirdparty/AES(节选):

text 复制代码
thirdparty/AES/
├── HPKBUILD
├── SHA512SUM
├── tiny-AES-c-1.0.0.tar.gz          # cleanbuild 后可能不存在,需重新下载
├── tiny-AES-c-1.0.0/
│   ├── aes.c, aes.h, test.c
│   ├── CMakeLists.txt               # 已被 prepare 覆盖
│   ├── arm64-v8a-build/             # cmake + make 产物
│   │   ├── libtiny-aes.a
│   │   ├── tiny_aes_test
│   │   └── ...
│   └── armeabi-v7a-build/
└── AES-1.0.0-arm64-v8a-lycium_build.log

lycium 安装树(节选):

text 复制代码
lycium/usr/AES/arm64-v8a/
├── bin/tiny_aes_test
├── include/aes.h
├── lib/libtiny-aes.a
└── hnp.json                         # archive 前复制进来

排错速查(和 HPKBUILD 强相关)

现象 建议排查
ERROR during : download download.log 、网络、URL;可改 sourcecodeload(本库已用)。
SHA512SUM 校验失败 下载包是否更新、SHA512SUM 是否与新包一致。
cmake 报找不到编译器 / sysroot OHOS_SDK 是否设置、SDK 是否完整。
prepare / source HPKBUILD 奇怪语法错误 CRLF :对 HPKBUILD 本身 也应用 LF(本技能常见要求)。
pack: command not found(旧问题) archive 里应对 hnpcli-x 判断(本仓库已处理)。
设备上 ctest 找不到目录 HPKCHECK 必须 cd "${builddir}/${ARCH}-build" ,与 -B"$ARCH-build" 一致。

库根 last_error 文件在 sure 失败时由 build_hpk.sh 写入一行错误信息,可与 buildlog 对照。


升级上游或改架构时:建议核对清单

  • pkgversource 中的版本片段、builddirpackagename 一致。
  • SHA512SUM 已用新 tarball 更新。
  • hnp.jsonversionREADME.OpenSource 的 Version Number、文档中的版本号。
  • archs 增删后,HPKCHECKcd 仍指向 ${builddir}/${ARCH}-build (若你改成嵌套 $builddir/ohos_build/${ARCH}-build 等,两边必须一起改)。
  • 上游 test.c / aes.c 文件名变更 时,prepareCRLF 列表CMake add_library 源文件 同步。

内嵌的 CMake 片段(在 prepare 里)在说什么?

  • add_library(tiny-aes STATIC aes.c):单文件静态库。
  • target_include_directories(... PUBLIC ...):对外暴露头文件路径,修正上游错误。
  • tiny_aes_test :链接 tiny-aes,跑上游自测。
  • enable_testing + add_test :注册 CTest ,与 HPKCHECKctest 对应。
  • install(...) :与 package()lib/include/bin 布局一致,便于以后若改为 cmake --install 时少改脚本。

总结

  • HPKBUILD = 变量(谁、版本、从哪下、编哪些架构、依赖谁) + 函数(准备、编译、安装、打包、提示、清理) ;真正 下载/校验/多架构循环build_hpk.sh 里,HPKBUILD 只声明「做什么」
  • build()"$@" 来自 cmakedependpath ,核心是指定 OHOS toolchain、安装前缀、OHOS_ARCH ;本库 depends ,故无 CMAKE_FIND_ROOT_PATH 拼接
  • prepare 解决 CRLF + 上游 CMake 路径错误 ,并打通 CTestpackage 把产物落到 usr/AES/$ARCHarchivetar + 可选 HNP
  • 排错优先看 库根 *-lycium_build.logdownload.loglast_error ;升级时 版本号与 SHA512SUMhnp.json、OpenSource 一并改。

更偏「流程叙述」的图文可继续阅读仓库内 鸿蒙PC tiny-AES-c三方库适配实践.md


相关文档

相关推荐
d1z8882 小时前
(十七)32天GPU测试从入门到精通-vLLM 部署与性能测试day15
服务器·显卡·nvidia·vllm
李游Leo2 小时前
别让压图拖垮首帧:系统 Picker + TaskPool + ImagePacker,把 HarmonyOS 图片整理链路做顺
harmonyos
2401_839633912 小时前
鸿蒙flutter第三方库适配 - 存储空间分析
flutter·华为·harmonyos
cyber_两只龙宝2 小时前
【Oracle】Oracle之DQL中SELECT的基础使用
linux·运维·服务器·数据库·云原生·oracle
Deitymoon2 小时前
linux——TCP多进程并发服务器
linux·服务器·tcp/ip
Hello World . .3 小时前
linux驱动编程2 : uboot、Linux内核、rootfs来源及制作流程
linux·运维·服务器
加农炮手Jinx3 小时前
Flutter 三方库 better_commit 的鸿蒙化适配指南 - 实现具备语义化提交规范与自动化交互的 Git 工作流插件、支持端侧版本工程的高效规范化审计实战
flutter·harmonyos·鸿蒙·openharmony·better_commit
麒麟ZHAO3 小时前
鸿蒙flutter第三方库适配 - 文件搜索工具
flutter·华为·harmonyos
啦啦啦_99993 小时前
1. Linux常用命令
linux·运维·服务器