读懂 hnp.json:鸿蒙PC 三方库打包时的这张「小配置」

欢迎大家加入鸿蒙PC开发者社区

前言

lycium 适配 OpenHarmony / 鸿蒙三方库时,有些仓库根目录会放一个 hnp.json。它只有几行,看起来像普通 JSON,作用却和 打包、分发 有关:告诉工具链(常见是 hnpcli)——这是一份 HNP 相关配置,里面写着组件叫什么、版本多少,以及可选的安装规则。

本文以本仓库 thirdparty/AES/hnp.json 为例,逐个字段说明含义,并说明它和 HPKBUILDarchive() 是怎么配合的。读完你可以自己判断:要不要维护这个文件升级版本时要改哪里


hnp.json 在本仓库里长什么样?

当前内容如下(便于对照,与仓库文件一致):

{
    "type": "hnp-config",
    "name": "tiny-AES-c",
    "version": "1.0.0",
    "install": {}
}

下面按字段解释;最后再说明 install 为什么是空对象


每个字段代表什么?

字段 通俗含义 本仓库示例 说明
type 配置文件的 类型标识 "hnp-config" 固定含义:这是 HNP 打包用的配置文件。工具(如 hnpcli)读到这个值,就知道要按「HNP 配置」来解析,而不是别的 JSON。不要改成随意字符串,否则工具可能不认。
name 组件 / 包的 显示名称 "tiny-AES-c" 一般与 上游库名 一致,方便在产物、清单里识别「这是哪套库」。注意:lycium 的 pkgnameAES(目录名),而这里 name 更偏向 产品/上游名称,两者可以不同,各司其职。
version 组件 版本号 "1.0.0" 建议与 HPKBUILD 里的 pkgver、上游 tag(如 v1.0.0)保持一致。升级源码版本时,记得同步改这里,避免「包里写的是 1.0.0,实际已是别的版本」这类混乱。
install 安装规则(拷贝路径、权限等) {} 空对象 表示:不在 JSON 里写复杂安装映射,而是依赖 package() 已经放好的目录结构(本库为 lib/include/bin/)。若平台或 hnpcli 要求声明额外规则,可在此按官方文档扩展;本库当前保持默认即可。

一句话: type 说「这是什么配置文件」,name/version 说「是谁、哪一版」,install 说「怎么装」——本库用空对象表示走默认目录布局。


它和 HPKBUILDarchive() 是什么关系?

构建流程里,package() 会把 libtiny-aes.aaes.htiny_aes_test 放进 $LYCIUM_ROOT/usr/AES/$ARCH/ 下的标准子目录。之后若定义了 archive()(本仓库已定义),会做几件事(与理解 hnp.json 相关的部分):

  1. thirdparty/AES/hnp.json 存在,会先 复制到 usr/AES/$ARCH/ 根目录(与 libinclude 同级),再打压缩包或供 hnpcli pack 使用。
  2. hnpcli 通常从 $HNP_TOOL$OHOS_SDK/toolchains/hnpcli 查找;若本机没有可执行文件,脚本会 跳过 pack,只记日志,不强制失败

因此:hnp.json 不是给 C 编译器看的,而是给 打包 / 分发链路 用的;没有跑 archive() 或没有 hnpcli 时,你仍然可以正常 交叉编译和安装到 usr/...,只是不会生成 HNP 侧产物。


维护时容易忽略的点

  • versionpkgver / hnp.json / 文档 建议一起改,避免版本漂移。
  • hnp.json 必须与 HPKBUILD 同目录;复制到安装目录时应用 "${PWD}/hnp.json",避免相对路径写错(例如误用 ../hnp.json)。
  • 若团队 完全不使用 HNP 打包,可以保留最小 hnp.json 以备将来接入,或在流程上明确「不执行 archive()」;以项目规范为准。

总结

  • hnp.jsonHNP 场景下的轻量配置,核心是 type(固定为 hnp-config)name(组件名)version(版本)install(安装规则,本库为空表示默认)
  • 它与 lycium 的 archive()hnpcli pack 配合,服务于 产物打包与分发不参与 编译 aes.c 本身。
  • 日常升级上游或发版时,优先核对 version 是否与 HPKBUILD 一致,再根据平台文档决定是否扩展 install

如需结合 鸿蒙PC tiny-AES-c三方库适配实践.md 里的「6.1 hnp.json」小节,可与本文对照阅读:实践文档偏 流程步骤,本文偏 字段语义与维护


实战案例:如何修改 hnp.json

场景一:升级上游版本

假设上游 tiny-AES-c 发布了 v1.1.0,你需要更新适配:

{
    "type": "hnp-config",
    "name": "tiny-AES-c",
    "version": "1.1.0",  // 从 1.0.0 改为 1.1.0
    "install": {}
}

同步修改清单:

  1. HPKBUILD 中的 pkgver="1.1.0"
  2. README.OpenSource 中的 Version Number
  3. SHA512SUM 文件(用新 tarball 重新计算)
  4. 相关文档中的版本号引用

场景二:添加安装规则

如果需要在 HNP 包中包含额外的配置文件或示例:

{
    "type": "hnp-config",
    "name": "tiny-AES-c",
    "version": "1.0.0",
    "install": {
        "include": ["aes.h", "aes_config.h"],
        "lib": ["libtiny-aes.a"],
        "bin": ["tiny_aes_test"],
        "extra": {
            "examples": "share/tiny-AES-c/examples"
        }
    }
}

注意: 添加 install 规则后,需要验证 hnpcli pack 是否能正确处理。

场景三:多组件打包

如果一个仓库包含多个独立组件(如 AES + DES):

{
    "type": "hnp-config",
    "name": "tiny-AES-c",
    "version": "1.0.0",
    "components": {
        "aes": {
            "name": "tiny-aes",
            "files": ["libtiny-aes.a", "aes.h"]
        },
        "des": {
            "name": "tiny-des",
            "files": ["libtiny-des.a", "des.h"]
        }
    },
    "install": {}
}

常见问题与解决方案

Q1: hnp.json 缺失会怎样?

A: 如果 thirdparty/AES/hnp.json 不存在:

  • 构建阶段build()package() 正常执行,产物安装到 usr/AES/$ARCH/
  • 打包阶段archive() 中复制 hnp.json 会失败,但脚本会跳过错误继续执行
  • HNP 打包hnpcli pack 无法执行,因为没有配置文件

建议: 即使暂时不用 HNP 打包,也保留最小化的 hnp.json

Q2: type 字段可以自定义吗?

A: 不建议。type: "hnp-config" 是工具链识别配置文件类型的关键标识。如果改成其他值:

  • hnpcli 可能无法识别并拒绝处理
  • 其他依赖 HNP 规范的工具也会失效

Q3: name 和 pkgname 为什么不同?

A: 它们服务于不同目的:

  • pkgname (HPKBUILD):lycium 内部标识,用于目录名、构建命令、依赖解析
  • name (hnp.json):HNP 包的显示名称,面向最终用户,通常与上游项目名一致

例如:

  • pkgname = "AES" → 构建命令 ./build.sh AES
  • name = "tiny-AES-c" → HNP 包名 tiny-AES-c-1.0.0.hnp

Q4: version 不一致会怎样?

A: 如果 hnp.json 的 version 与 HPKBUILDpkgver 不一致:

  • 构建产物:使用 pkgver 版本的源码
  • HNP 包元数据:使用 hnp.json 的 version
  • 结果:包名与内容不匹配,用户安装后可能遇到版本混乱

最佳实践: 在 CI/CD 中添加检查脚本,确保两者一致。


与其他配置文件的关系

与 HPKBUILD 的配合

HPKBUILD (构建逻辑)
    ↓
package() (安装产物到 usr/)
    ↓
archive() (复制 hnp.json + 打包)
    ↓
hnpcli pack (读取 hnp.json 生成 HNP 包)

关键点:

  • HPKBUILD 决定 构建什么
  • hnp.json 决定 如何打包和分发
  • 两者通过 archive() 函数连接

与 README.OpenSource 的对应

字段 hnp.json README.OpenSource
名称 name Name (第一条)
版本 version Version Number
协议 License

说明: hnp.json 不包含许可证信息,因为:

  • 许可证已在源码和产物中体现
  • HNP 包管理器通常有独立的许可证数据库
  • 避免重复维护

验证与测试

验证 hnp.json 格式

# 使用 jq 验证 JSON 格式
jq . hnp.json

# 或使用 python
python -m json.tool hnp.json

测试 HNP 打包流程

# 1. 构建库
./build.sh AES

# 2. 检查产物
ls -l lycium/usr/AES/arm64-v8a/

# 3. 检查 hnp.json 是否被复制
ls -l lycium/usr/AES/arm64-v8a/hnp.json

# 4. 手动测试 hnpcli(如果可用)
hnpcli pack lycium/usr/AES/arm64-v8a/

常见错误排查

错误现象 可能原因 解决方法
hnp.json not found 文件不存在或路径错误 检查 archive() 中的复制路径
Invalid JSON 格式错误(缺少逗号、引号等) 使用 jqjson.tool 验证
Unknown type type 字段值不正确 改为 "hnp-config"
hnpcli: command not found 工具未安装 安装 HNP 工具链或跳过打包

最佳实践总结

1. 版本同步

# 检查脚本示例
#!/bin/bash
pkgver=$(grep "^pkgver=" HPKBUILD | cut -d= -f2)
hnp_ver=$(jq -r .version hnp.json)

if [ "$pkgver" != "$hnp_ver" ]; then
    echo "ERROR: Version mismatch!"
    echo "  HPKBUILD: $pkgver"
    echo "  hnp.json: $hnp_ver"
    exit 1
fi

2. 最小化原则

如果不需要特殊安装规则,保持 install 为空对象:

{
    "type": "hnp-config",
    "name": "tiny-AES-c",
    "version": "1.0.0",
    "install": {}
}

3. 文档化

README_zh.md 中说明 HNP 包的使用方式:

## HNP 包使用

本库提供 HNP 格式的预编译包,可通过以下方式安装:

\`\`\`bash
hnpcli install tiny-AES-c-1.0.0.hnp
\`\`\`

安装后,头文件和库文件位于标准路径。

扩展阅读

HNP 包格式规范

HNP (HarmonyOS Native Package) 是鸿蒙生态的原生包格式,特点:

  • 支持多架构(arm64-v8a, armeabi-v7a)
  • 包含元数据(名称、版本、依赖)
  • 支持安装脚本和卸载脚本
  • 与 OpenHarmony 包管理系统集成

相关工具

  • hnpcli:HNP 包管理命令行工具
  • hnp-build:HNP 包构建工具
  • hnp-registry:HNP 包仓库服务

Logo

开源鸿蒙跨平台开发社区汇聚开发者与厂商,共建“一次开发,多端部署”的开源生态,致力于降低跨端开发门槛,推动万物智联创新。

更多推荐