已开启
feat: 新增 community/binn 三方库适配 #2276
feat: 新增 community/binn 三方库适配 #2276
已开启
STF-Zero创建于 22 天前
共 12 个文件变更+425-0
@@ -0,0 +1,188 @@
1+# Copyright (c) 2026 STF-Zero
2+# Licensed under the Apache License, Version 2.0 (the "License");
3+# you may not use this file except in compliance with the License.
4+# You may obtain a copy of the License at
5+#
6+# http://www.apache.org/licenses/LICENSE-2.0
7+#
8+# Unless required by applicable law or agreed to in writing, software
9+# distributed under the License is distributed on an "AS IS" BASIS,
10+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
11+# See the License for the specific language governing permissions and
12+# limitations under the License.
13+#
14+# Contributor: STF-Zero <caoningxu@gmail.com>
15+# Maintainer: STF-Zero <caoningxu@gmail.com>
16+# buildtools=make HPKBUILD 骨架
17+pkgname=binn
18+pkgver=3.0
19+pkgrel=0
20+pkgdesc="Binn is a compact, fast and easy to use binary data serialization format and C library"
21+url="https://github.com/liteserver/binn"
22+license=("Apache-2.0")
23+makedepends=()
24+source="https://github.com/liteserver/binn/archive/refs/tags/v3.0.tar.gz"
25+archs=("armeabi-v7a" "arm64-v8a" "x86_64")
26+builddir=${pkgname}-${pkgver}
27+buildtools="make"
28+downloadpackage=true
29+autounpack=false
30+packagename=${pkgname}-${pkgver}.tar.gz
31+patchflag=true
32+depends=()
33+ 
34+prepare() {
35+ cd ${PKGBUILD_ROOT}
36+ extract_archive() {
37+ local _arc="$1" _dst="$2"
38+ cd "$_dst" || return 1
39+ case "$_arc" in
40+ *.tar.gz|*.tgz) tar -xzf "$_arc" ;;
41+ *.zip) unzip -qo "$_arc" ;;
42+ *) echo "unsupported archive: $_arc"; return 1 ;;
43+ esac
44+ }
45+ if [ ! -d "$builddir" ]; then
46+ extract_archive "${packagename}" "${PKGBUILD_ROOT}" || return 1
47+ fi
48+ # 目录名规范化:解压目录可能与 $builddir 不同名(pkgver 带 v 前缀、
49+ # GitHub 归档含 commit hash),finalize 清源重建时依赖此逻辑
50+ if [ ! -d "$builddir" ]; then
51+ for _d in *; do
52+ if [ -d "$_d" ] && [ "$_d" != "logs" ] && [ "$_d" != "hpkbuild_history" ] && ! echo "$_d" | grep -q -- '-build$'; then
53+ if [ -f "$_d/CMakeLists.txt" ] || [ -f "$_d/configure" ] || [ -f "$_d/Makefile" ] || [ -f "$_d/makefile" ]; then
54+ mv "$_d" "$builddir" 2>/dev/null && break
55+ fi
56+ fi
57+ done
58+ fi
59+ # 唯一目录兜底:patch 创建构建系统的库在打补丁前无构建标记,唯一普通
60+ # 目录直接规范化(poly1305 真实案例);多个候选时 fail closed。
61+ if [ ! -d "$builddir" ]; then
62+ _candidates=()
63+ for _d in *; do
64+ if [ -d "$_d" ] && [ "$_d" != "logs" ] && [ "$_d" != "hpkbuild_history" ] && [ "${_d:0:1}" != "." ] && ! echo "$_d" | grep -q -- '-build$'; then
65+ _candidates+=("$_d")
66+ fi
67+ done
68+ if [ "${#_candidates[@]}" -eq 1 ]; then
69+ mv "${_candidates[0]}" "$builddir" 2>/dev/null || return 1
70+ fi
71+ fi
72+ [ -d "$builddir" ] || return 1
73+ # 双层嵌套规范化(nspr 实证):归档根 builddir/ 内含唯一源码目录
74+ # (如 builddir/nspr/ 有 configure)时提升到 builddir,否则 build() 在
75+ # 错误目录触发 autoreconf -> "configure.ac is required"。
76+ if [ ! -f "$builddir/configure" ] && [ ! -f "$builddir/configure.ac" ] && [ ! -f "$builddir/CMakeLists.txt" ] && [ ! -f "$builddir/Makefile" ] && [ ! -f "$builddir/makefile" ]; then
77+ _inner=""
78+ for _d in "$builddir"/*/; do
79+ [ -d "${_d%/}" ] || continue
80+ case "${_d%/}" in *-build|*logs*|*hpkbuild_history*) continue;; esac
81+ if [ -f "${_d}configure" ] || [ -f "${_d}configure.ac" ] || [ -f "${_d}configure.in" ] || [ -f "${_d}CMakeLists.txt" ] || [ -f "${_d}Makefile" ] || [ -f "${_d}makefile" ] || [ -f "${_d}meson.build" ]; then
82+ if [ -z "$_inner" ]; then _inner="${_d%/}"; else _inner=""; break; fi
83+ fi
84+ done
85+ if [ -n "$_inner" ]; then
86+ mv "$_inner" "${builddir}-__inner"
87+ rm -rf "$builddir"
88+ mv "${builddir}-__inner" "$builddir"
89+ echo "[nest] 双层嵌套源码已提升: $builddir" >> $buildlog
90+ fi
91+ fi
92+ # patch 应用:H+P 项目 clean rebuild 必须重放补丁(poly1305 真实案例)
93+ if $patchflag; then
94+ cd "$builddir" || return 1
95+ if [ ! -f .oh_patch_applied ]; then
96+ _PATCHED=0
97+ for _pl in 1 0 2; do
98+ patch -N -p${_pl} --batch --forward < "../${pkgname}_oh_pkg.patch" >/dev/null 2>&1
99+ _rc=$?
100+ if [ $_rc -eq 0 ]; then _PATCHED=1; break; fi
101+ _first=$(grep -m1 '^+++' "../${pkgname}_oh_pkg.patch" | sed 's/^+++ //; s/ .*//; s/^[ab]\///')
102+ if [ -n "$_first" ] && [ -f "$_first" ]; then _PATCHED=1; break; fi
103+ done
104+ [ "$_PATCHED" -eq 1 ] || { echo "patch 应用失败(-p1/-p0/-p2 均无效)" >> $buildlog; return 1; }
105+ touch .oh_patch_applied
106+ fi
107+ cd ${PKGBUILD_ROOT}
108+ fi
109+ source envset.sh
110+ rm -rf ${builddir}-${ARCH}-build
111+ cp -r ${builddir} ${builddir}-${ARCH}-build
112+ return 0
113+}
114+ 
115+build() {
116+ cd ${PKGBUILD_ROOT}/${builddir}-${ARCH}-build || return 1
117+ # 按 ARCH 加载交叉编译环境(source envset.sh 只定义函数,必须调用
118+ # setarm32ENV/setarm64ENV/setx86_64ENV 才会设置 CC/AR/RANLIB——否则 make 得到空 CC)
119+ source envset.sh 2>/dev/null
120+ case "${ARCH}" in
121+ armeabi-v7a) setarm32ENV ;;
122+ arm64-v8a) setarm64ENV ;;
123+ x86_64) setx86_64ENV ;;
124+ *) echo "unsupported ARCH: ${ARCH}" >&2; return 1 ;;
125+ esac
126+ export CC AR RANLIB CFLAGS LDFLAGS
127+ # CFLAGS 合并铁律:命令行 `make CFLAGS=...` 会**整体覆盖** Makefile 内的
128+ # `CFLAGS += -O3 -Wall ...`(GNU make 命令行变量优先于所有赋值,含 +=),
129+ # 把上游优化/告警标志一并丢掉。因此仅在 makefile 对 CFLAGS **硬赋值**
130+ # (`CFLAGS =` / `CFLAGS ?=`)时才走命令行覆盖并补 -fPIC;否则交给已
131+ # export 的环境变量,OHOS 与上游标志天然并存(环境变量对 `+=` 是追加)。
132+ # 包特异:binn 3.0 的构建文件是小写 `makefile`(GNU make 依次查找
133+ # GNUmakefile/makefile/Makefile),故统一循环探测。
134+ _mk_extra=()
135+ for _mkf in GNUmakefile Makefile makefile; do
136+ if [ -f "$_mkf" ] && grep -qE '^[[:space:]]*CFLAGS[[:space:]]*(\?=|=)' "$_mkf"; then
137+ _mk_extra=(CFLAGS="${CFLAGS} -fPIC")
138+ break
139+ fi
140+ done
141+ # 同时构建共享库与静态库(默认目标 all 只产出 libbinn.so.3.0)
142+ make -j${JOB:-4} CC="${CC}" AR="${AR}" RANLIB="${RANLIB}" ${_mk_extra[@]+"${_mk_extra[@]}"} all static >> $buildlog 2>&1 || return 1
143+}
144+ 
145+package() {
146+ cd ${PKGBUILD_ROOT}/${builddir}-${ARCH}-build || return 1
147+ # 安装前缀:遵循 lycium 约定 usr/${pkgname}/${ARCH}。
148+ # 历史故障:旧代码用未定义变量 ${INSTALL_PREFIX}(lycium 中不存在),
149+ # 展开为空 -> make install PREFIX= -> 产物写到根目录 /include 触发
150+ # "mkdir: cannot create directory '/include': Permission denied"。
151+ _pkg_prefix="${LYCIUM_ROOT:-${PKGBUILD_ROOT}/../../lycium}/usr/${pkgname}/${ARCH}"
152+ echo "[package] install prefix = ${_pkg_prefix}" >> $buildlog
153+ mkdir -p "${_pkg_prefix}/lib" "${_pkg_prefix}/include" || return 1
154+ # binn makefile 中 PREFIX := /usr/local(硬赋值),命令行 PREFIX= 可覆盖。
155+ make install PREFIX="${_pkg_prefix}" prefix="${_pkg_prefix}" >> $buildlog 2>&1
156+ _install_rc=$?
157+ # make install 缺失/失败/未安装头文件时回退为手工安装,避免整包交付失败
158+ if [ "$_install_rc" -ne 0 ] || [ ! -f "${_pkg_prefix}/include/binn.h" ]; then
159+ echo "[package] make install 返回 ${_install_rc} 或未安装头文件,回退为手工安装库与头文件" >> $buildlog
160+ _installed=0
161+ for _lib in libbinn.so* libbinn-3.0.so* libbinn.a binn.a; do
162+ [ -e "$_lib" ] || continue
163+ cp -a "$_lib" "${_pkg_prefix}/lib/" || return 1
164+ _installed=1
165+ done
166+ if [ -f src/binn.h ]; then
167+ cp -f src/binn.h "${_pkg_prefix}/include/" || return 1
168+ fi
169+ [ "$_installed" -eq 1 ] || { echo "未找到可安装的库产物" >> $buildlog; return 1; }
170+ fi
171+ # 兜底:确保 libbinn.so 与 libbinn.a 软链存在
172+ if [ -e "${_pkg_prefix}/lib/libbinn.so.3.0" ] && [ ! -e "${_pkg_prefix}/lib/libbinn.so" ]; then
173+ ln -sf libbinn.so.3.0 "${_pkg_prefix}/lib/libbinn.so" 2>/dev/null
174+ fi
175+ [ -f "${_pkg_prefix}/include/binn.h" ] || return 1
176+ [ -e "${_pkg_prefix}/lib" ] || return 1
177+ return 0
178+}
179+ 
180+cleanbuild() {
181+ cd ${PKGBUILD_ROOT}
182+ rm -rf ${PWD}/${builddir} ${PWD}/${builddir}-*-build
183+ return 0
184+}
185+ 
186+check() {
187+ echo "The test must be on an OpenHarmony device!"
188+}
@@ -0,0 +1,58 @@
1+#!/bin/sh
2+# Copyright (c) 2026 STF-Zero
3+# Licensed under the Apache License, Version 2.0 (the "License");
4+# you may not use this file except in compliance with the License.
5+# You may obtain a copy of the License at
6+#
7+# http://www.apache.org/licenses/LICENSE-2.0
8+#
9+# Unless required by applicable law or agreed to in writing, software
10+# distributed under the License is distributed on an "AS IS" BASIS,
11+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+# See the License for the specific language governing permissions and
13+# limitations under the License.
14+#
15+# Contributor: STF-Zero <caoningxu@gmail.com>
16+# Maintainer: STF-Zero <caoningxu@gmail.com>
17+# HARNESS_EXPECTED_CASES = 2
18+# HARNESS_TEST_ORIGIN = harness_authored
19+# HARNESS_HPKCHECK_AUTOGENERATED = 1
20+# HARNESS_SMOKE_SOURCE = consumer_smoke(binn.h + libbinn.so)
21+# HARNESS_RUNTIME_FILES = harness_smoke/binn_smoke harness_smoke/harness_symbol_probe
22+# HARNESS_RUNTIME_INSTALL = full
23+. ./HPKBUILD >/dev/null 2>&1
24+logfile=${LYCIUM_THIRDPARTY_ROOT}/${pkgname}/${pkgname}_${ARCH}_harness_test.log
25+build_root=${LYCIUM_THIRDPARTY_ROOT}/${pkgname}/${builddir}-${ARCH}-build
26+checkprepare() {
27+ for _d in "${LYCIUM_ROOT}"/usr/*/"${ARCH}"/lib; do
28+ [ -d "$_d" ] && LD_LIBRARY_PATH="${_d}:${LD_LIBRARY_PATH}"
29+ done
30+ export LD_LIBRARY_PATH
31+}
32+run_case() {
33+ case_name=$1
34+ binary=$2
35+ shift 2
36+ case_log=${logfile}.${case_name}
37+ if [ ! -x "${binary}" ]; then
38+ echo "missing harness smoke executable: ${binary}" > "${case_log}"
39+ result=1
40+ else
41+ (cd "${build_root}" && "${binary}" "$@") > "${case_log}" 2>&1
42+ result=$?
43+ fi
44+ cat "${case_log}" >> "${logfile}"
45+ if [ ${result} -eq 0 ]; then
46+ echo "HARNESS_CASE ${case_name} PASS" | tee -a "${logfile}"
47+ else
48+ echo "HARNESS_CASE ${case_name} FAIL" | tee -a "${logfile}"
49+ fi
50+ return ${result}
51+}
52+openharmonycheck() {
53+ : > "${logfile}"
54+ status=0
55+ run_case harness-smoke "${build_root}/harness_smoke/binn_smoke" || status=1
56+ run_case symbol-probe "${build_root}/harness_smoke/harness_symbol_probe" "libbinn.so" "binn_add_value" "binn_copy" "binn_count" || status=1
57+ return ${status}
58+}
@@ -0,0 +1,16 @@
1+<?xml version="1.0" encoding="UTF-8"?>
2+<configuration>
3+ <oatconfig>
4+ <filefilterlist>
5+ <filefilter name="copyrightPolicyFilter" desc="Filters for compatibility,license header policies">
6+ <filteritem type="filename" name="SHA512SUM" desc="SHA512SUM文件,不添加版权头"/>
7+ </filefilter>
8+ <filefilter name="defaultPolicyFilter" desc="Filters for compatibility,license header policies">
9+ <filteritem type="filename" name="SHA512SUM" desc="SHA512SUM文件,不添加版权头"/>
10+ </filefilter>
11+ <filefilter name="binaryFileTypePolicyFilter" desc="Filters for resources files policies">
12+ <filteritem type="filename" name="*.png" desc="指导文档需要的png图片"/>
13+ </filefilter>
14+ </filefilterlist>
15+ </oatconfig>
16+</configuration>
@@ -0,0 +1,11 @@
1+[
2+ {
3+ "Name": "binn",
4+ "License": "Apache-2.0",
5+ "License File": "https://github.com/liteserver/binn/blob/master/LICENSE",
6+ "Version Number": "3.0",
7+ "Owner": "caoningxu@gmail.com",
8+ "Upstream URL": "https://github.com/liteserver/binn",
9+ "Description": "Binn is a compact, fast and easy to use binary data serialization format and C library"
10+ }
11+]
@@ -0,0 +1,27 @@
1+# binn三方库说明
2+ 
3+## 功能简介
4+ 
5+Binn is a compact, fast and easy to use binary data serialization format and C library
6+ 
7+- 上游地址:https://github.com/liteserver/binn
8+- 版本:3.0
9+- 开源协议:Apache-2.0
10+- 支持的架构:armeabi-v7a, arm64-v8a, x86_64
11+- 构建方式:make
12+ 
13+## 三方库版本
14+ 
15+- 3.0
16+ 
17+## 已适配功能
18+ 
19+- Binn is a binary data serialization format designed to be compact, fast and easy to use
20+ 
21+## 使用约束
22+ 
23+- [IDE和SDK版本](../../docs/constraint.md)
24+ 
25+## 集成方式
26+ 
27+[应用包hap集成](docs/hap_integrate.md)
@@ -0,0 +1 @@
1+a285e71be024bab2c669d5528ebc0240658085e3fdd8d5c99091813aa3029e2d5655ec461fbf49347e7b98945f968c5a1ce834ebcca5e7844297f6c4da348a44 binn-3.0.tar.gz
@@ -0,0 +1,18 @@
1+diff --git a/src/binn.h b/src/binn.h
2+index 9f1b06c..c6a3def 100644
3+--- a/src/binn.h
4++++ b/src/binn.h
5+@@ -7,6 +7,13 @@
6+ #ifndef BINN_H
7+ #define BINN_H
8+
9++/* size_t is used in binn_set_alloc_functions() prototypes below.
10++ * The upstream header relied on the including TU to have already pulled in
11++ * a definition of size_t; when consumed standalone on Musl/OHOS that fails
12++ * with "a parameter list without types is only allowed in a function
13++ * definition". Pull it in explicitly so the header is self-contained. */
14++#include <stddef.h>
15++
16+ #ifdef __cplusplus
17+ extern "C" {
18+ #endif
@@ -0,0 +1,106 @@
1+# binn如何集成到应用hap
2+ 
3+本库已基于 OpenHarmony 镜像完成交叉编译与设备端加载验证(版本 3.0)。
4+ 
5+实测环境:`arm64-v8a`(QEMU 裁剪镜像(模拟),目标 `127.0.0.1:5855`,`uname -m=aarch64`);`armeabi-v7a`(QEMU 裁剪镜像(模拟),目标 `127.0.0.1:5755`,`uname -m=armv7l`);`x86_64`(DevEco 官方模拟器(模拟),目标 `127.0.0.1:15555`,`uname -m=x86_64`)。
6+ 
7+以上均为**模拟运行环境,不是物理真机**;真机(开发板/手机/平板)验证:**未做**(上方均为模拟环境)。
8+社区标准验证环境为 [润和 RK3568 开发板](https://gitee.com/openharmony-sig/knowledge_demo_temp/tree/master/docs/rk3568_helloworld)(OpenHarmony 3.2 Release 镜像),本库未使用该开发板;验证过程与结果见 `docs/pic/` 截图。
9+ 
10+## 准备应用工程
11+ 
12+### 准备应用开发环境
13+ 
14+- [开发环境准备](../../../docs/hap_integrate_environment.md)
15+ 
16+### 增加构建脚本及配置文件
17+ 
18+本库的构建脚本与配置文件:`HPKBUILD`(交叉编译脚本)、`HPKCHECK`(设备端测试入口)、`OAT.xml`(版权头豁免),详见 [HPKBUILD](../HPKBUILD) 与 [HPKCHECK](../HPKCHECK)。
19+ 
20+应用工程侧,在最外层(cpp 目录下)`CMakeLists.txt` 中添加如下语句:
21+ 
22+```shell
23+ #将三方库加入工程中
24+ target_link_libraries(entry PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/binn/${OHOS_ARCH}/lib/libbinn.so)
25+ 
26+ #将三方库的头文件加入工程中
27+ target_include_directories(entry PRIVATE ${CMAKE_CURRENT_SOURCE_DIR}/thirdparty/binn/${OHOS_ARCH}/include)
28+```
29+ 
30+### 准备三方库源码
31+ 
32+- 下载本仓库
33+ 
34+ ```shell
35+ git clone https://gitcode.com/CPF-ApplicationTPC/tpc_c_cplusplus.git --depth=1
36+ ```
37+ 
38+- 三方库目录结构
39+ 
40+ ```shell
41+ tpc_c_cplusplus/community/binn #三方库binn的目录结构如下
42+ ├── docs #三方库相关文档的文件夹
43+ ├── HPKBUILD #构建脚本
44+ ├── HPKCHECK #测试脚本
45+ ├── SHA512SUM #三方库校验文件
46+ ├── OAT.xml #OAT开源审查文本文件
47+ ├── README.OpenSource #说明三方库源码的下载地址,版本,license等信息
48+ ├── README_zh.md #三方库简介
49+ ```
50+ 
51+## 应用中使用三方库
52+ 
53+- 在IDE的cpp目录下新增thirdparty目录,将编译产物 `lycium/usr/binn/<abi>/` 下的 `include/` 与 `lib/` 拷贝进去,形成 `cpp/thirdparty/binn/<abi>/{include,lib}`(动态库名字带版本号和不带版本号的都需要;`share/`、`cmake/` 等非头文件/库内容可以不拷),如下图所示:
54+ 
55+ &nbsp;
56+ 
57+ &nbsp;![thirdparty_install_dir](pic/binn_install_dir.png)
58+ 
59+## 编译工程
60+ 
61+- 在lycium目录下编译三方库
62+ 
63+ 编译环境的搭建参考[准备三方库构建环境](../../../lycium/README.md#1编译环境准备)
64+ 
65+ ```shell
66+ cd lycium
67+ ./build.sh binn
68+ ```
69+ 
70+- 三方库头文件及生成的库
71+ 
72+ 在lycium目录下会生成usr目录,该目录下存在已编译完成的32位和64位三方库
73+ 
74+ ```shell
75+ binn/armeabi-v7a binn/arm64-v8a binn/x86_64
76+ ```
77+ 
78+- [测试三方库](#测试三方库)
79+ 
80+## 测试三方库
81+ 
82+- 上游未提供可独立交叉编译的测试套件,本库交付的是自撰的消费者冒烟用例与符号级探针,已随 `HPKCHECK` 下发设备执行。
83+ 
84+- 进入构建目录运行冒烟用例(`arm64-v8a` 为构建64位的目录,`armeabi-v7a` 为构建32位的目录),执行结果如图所示:
85+ 
86+```shell
87+ cd /data/tpc_c_cplusplus/thirdparty/binn/binn-3.0-arm64-v8a-build/
88+ ./harness_smoke/binn_smoke
89+ ./harness_smoke/harness_symbol_probe
90+```
91+ 
92+&nbsp;![arm64](pic/arm64.png)
93+&nbsp;![armv7a](pic/armv7a.png)
94+&nbsp;![x86_64](pic/x86_64.png)
95+ 
96+## 运行效果
97+ 
98+本库已完成设备端加载与用例验证(设备端执行记录见 `docs/pic/` 截图);应用侧(HAP)集成后的运行效果截图后续补充。
99+ 
100+## 参考资料
101+ 
102+- [润和RK3568开发板标准系统快速上手](https://gitee.com/openharmony-sig/knowledge_demo_temp/tree/master/docs/rk3568_helloworld)
103+- [OpenHarmony三方库地址](https://gitee.com/openharmony-tpc)
104+- [OpenHarmony知识体系](https://gitee.com/openharmony-sig/knowledge)
105+- [通过DevEco Studio开发一个NAPI工程](https://gitee.com/openharmony-sig/knowledge_demo_temp/blob/master/docs/napi_study/docs/hello_napi.md)
106+- 上游源码:https://github.com/liteserver/binn/archive/refs/tags/v3.0.tar.gz