开源鸿蒙 PC 三方库适配复盘:mbpoll 1.5.4,从“依赖根本没发布“到合入主线
本文是「开发者大学生创新大赛 · OpenHarmony PC 三方库积分赛」的一篇适配复盘。对象是 Modbus 主站命令行工具 mbpoll 1.5.4,对应 PR:build_in_harmonyos!2310,2026-07-15 提交,2026-07-24 合入 main 并发布到制品仓。
这个库代码量不大,但把积分赛里最常见的几类坑几乎踩了一遍:依赖库没发布到制品仓、上游构建脚本依赖 git 元数据、依赖库版本落后于调用方 API、musl 工具链缺内核头、老 config.guess 不认 HarmonyOS、HMDFS 文件系统的 umask 陷阱、CI 门禁与 worker 基础设施抖动。所以拿它来复盘,比拿一个"一次 conan create 就过"的库更有参考价值。
- 一、背景:为什么是 mbpoll
- 二、环境与工具链
- 三、动手前的侦察:先回答三个问题
- 四、核心难点:libmodbus 没发布,怎么办
- 五、逐个拆坑
- 六、测试:拿真数据,不编数据
- 七、CI 门禁与 PR 流转:一条真实的时间线
- 八、知识沉淀:从一次适配到一条可复用的模式
- 九、复盘总结
- 附:PR 文件清单
ounter(counterh2一、背景:为什么是 mbpoll
1.1 这个库是干什么的
mbpoll 是一个 Modbus 主站(Master)仿真工具,命令行一条指令就能读写 Modbus 从站的线圈、离散输入、保持寄存器和输入寄存器,支持 RTU(串口)和 TCP 两种传输。工控、能源、楼宇自控这些场景里,拿它当"Modbus 版的 curl"来调设备非常顺手。
-
上游:https://github.com/epsilonrt/mbpoll ,版本 1.5.4
-
语言 / 构建:C,CMake
-
许可证:GPL-3.0-only
-
唯一运行时依赖:libmodbus ≥ 3.1.7
1.2 为什么选它
积分赛选库有一条朴素原则:选生态价值高、又没人做、且自己能兜住的库。mbpoll 满足三条:
-
OpenHarmony PC 在工业和物联网场景要落地,Modbus 工具链是刚需,制品仓里当时连 libmodbus 都还没发布;
-
依赖只有一个 libmodbus,依赖树浅,适配周期可控;
-
上游自带 CTest 单元测试,PR 模板要求的"上游测试通过率"能拿到真实数据,而不是编一个 100%。
真做起来才发现,"依赖只有一个"和"依赖很好搞"是两回事。下面进入正题。
ounter(counterh2二、环境与工具链
| 项目 | 说明 |
|---|---|
| 目标平台 | OpenHarmony / HarmonyOS PC,aarch64,musl libc |
| 编译器 | CI worker 与本地构建容器:hnp 工具链下的 clang 15;真机复测:OHOS SDK clang 15.0.4 |
| 包管理 | Conan 2.x(conan create + test_package) |
| 本地验证 | 团队内部的 hmbs-builder 构建容器(原生 aarch64,可直接运行编译产物) |
| 真机复测 | HarmonyOS HAD 206.1.0 真机,OHOS SDK clang 15.0.4 |
| CI | build_in_harmonyos 仓库的 Buildbot worker,L0 结构门禁 + L1 测试执行门禁 |
有两点值得先说清楚,后面好几个坑都由它们引出:
-
本地容器
uname报 Linux,CI worker 报 HarmonyOS。 凡是 autotools 的config.guess探测平台,本地和 CI 走的分支不一样,本地绿了 CI 未必绿。 -
CI worker 的工作目录在 HMDFS(分布式文件系统)上,权限语义和普通 ext4 不同,某些"本地永远复现不了"的失败根源在这里。
ounter(counterh2三、动手前的侦察:先回答三个问题
在写第一行 conanfile 之前,我固定会先回答三个问题。这一步花 20 分钟,能省后面 2 小时。
问题 1:依赖在制品仓里吗?
翻 archives/l/libmodbus/,有 3.1.10 和 3.1.12 两个目录,manifest 里 status: built。看起来像"已发布",但再往下看:没有 conanfile.py,也没有任何一个配方 requires 它。也就是说它只是被人编译通过过,从来没有作为 Conan 包发布到 ohpcd 制品仓。按仓库规则(R36:依赖必须先发布),我不能 self.requires("libmodbus/...")。
教训:
status: built≠ 可requires。判断标准是"制品仓里能不能conan install到",不是 manifest 上写了什么。
问题 2:上游构建系统有什么不可移植的地方?
tar tzf 看一眼 mbpoll 源码包,cmake/GitVersion.cmake 引起了注意:它靠 git describe --tags 取版本号,取不到就 FATAL_ERROR。Conan 的 source() 解出来的是源码 tarball,不是 git 仓库,这一步必挂。
问题 3:上游测试长什么样?
tests/ 下两个 C 文件 test_utils.c、test_serial.c,纯手写断言,走 CTest。没有 GTest、没有 Python 绑定、不需要网络和真实串口。结论:上游测试可以在容器里真跑,通过率能拿实数。
侦察完,适配方案的骨架就定了:在配方里 vendor libmodbus 源码静态编译,打两枚补丁,上游测试本地实跑取数。
ounter(counterh2四、核心难点:libmodbus 没发布,怎么办
4.1 三条路的取舍
| 方案 | 优点 | 问题 |
|---|---|---|
| A. 先单独适配发布 libmodbus,再 requires | 最规范 | 要等另一个 PR 合入并发布,周期不可控;且 libmodbus 3.1.12 源码归档需要 autogen(见下) |
| B. 假设 CI worker 系统里有 libmodbus | 零工作量 | worker 环境异质,随时链接失败;仓库明令禁止 |
| C. 在配方内 vendor 源码,编成静态库链进 mbpoll | 自包含、可过 CI、产物只有一个二进制 | 配方复杂度上升;要处理子项目的一堆移植问题 |
选 C。这也是后来沉淀成知识条目 E215 的"vendored 依赖构建到 staging"模式。
4.2 一个意想不到的坑:源码包从哪下
libmodbus 有两处下载源,差别很大:
-
github.com/stephane/libmodbus/archive/refs/tags/vX.Y.Z.tar.gz:GitHub 自动生成的源码归档,只有autogen.sh,没有configure。而构建容器和 CI worker 都没有 autoconf/automake,autogen.sh跑不了。 -
libmodbus.org/releases/libmodbus-X.Y.Z.tar.gz:官方发布包,自带预生成的configure。但笔者 2026 年 7 月实测,只有 3.1.6 和 3.1.7 能下,3.1.8 及以上全部 404。
mbpoll 要求 libmodbus ≥ 3.1.7,3.1.7 刚好卡在门槛上。于是 conandata.yml 里第二个源就是它:
# sha256 已截断,以仓库中的 conandata.yml 为准
sources:
- url: "https://github.com/epsilonrt/mbpoll/archive/refs/tags/v1.5.4.tar.gz"
sha256: "a9bcc3af...9956f"
- url: "https://libmodbus.org/releases/libmodbus-3.1.7.tar.gz"
sha256: "7dfe9584...f8fbd"
folder: "libmodbus"
source() 里两份源分别解压:mbpoll 到源码根,libmodbus 到 libmodbus/ 子目录。
4.3 vendor 构建的骨架
整体流程:build() 里先用 autotools 把 libmodbus 编成静态库、make install 到 build 目录下的 libmodbus-root/,再让 mbpoll 的 CMake 通过 PKG_CONFIG_PATH 找到它。
def generate(self):
tc = CMakeToolchain(self)
tc.variables["BUILD_TESTING"] = False
tc.variables["MBPOLL_CUSTOM_RTS_GPIO"] = False # piduino GPIO,OHOS 没有
tc.cache_variables["CMAKE_SKIP_RPATH"] = True # 静态链接无需 RPATH,也绕开 CMakeRelink.dir
tc.generate()
# 把 vendored libmodbus 的 .pc 暴露给 mbpoll 的 pkg_check_modules()
lm_pkgconfig = os.path.join(self.build_folder, "libmodbus-root", "lib", "pkgconfig")
env = Environment()
env.define_path("PKG_CONFIG_PATH", lm_pkgconfig)
env.vars(self, scope="build").save_script("conan_libmodbus_pkgconfig")
def build(self):
apply_conandata_patches(self)
self._build_libmodbus()
cmake = CMake(self)
cmake.configure()
cmake.build()
整个流程画成一张图:

mbpoll 配方的 vendored libmodbus 构建流程:两份源码、三处补丁/shim、libmodbus 静态编译到 staging、mbpoll 经 PKG_CONFIG_PATH 链接、产物仅 bin/mbpoll
图 1:vendored 依赖构建流程(E215 模式)
_build_libmodbus() 是整个配方的重头戏,里面塞了四个移植修复,下一节逐个拆。
最终产物只有 bin/mbpoll,readelf -d 只看到 NEEDED libc.so,libmodbus 已经静态链进去了。这样既不用给额外的 .so 做代码签名,也不用操心运行时 LD_LIBRARY_PATH。
ounter(counterh2五、逐个拆坑
坑 1:上游用 git tag 取版本号,源码包构建直接中止
现象:cmake.configure() 阶段报 FATAL_ERROR,来自 cmake/GitVersion.cmake。
根因:GetGitVersion() 跑 git describe --tags,源码 tarball 不是 git 仓库。更阴险的是:即使构建树的上层目录恰好是一个不相关的 git 仓库,它也会因为找不到匹配的 tag 而 FATAL_ERROR,所以"把源码解压到某个 git 仓库下面"并不能绕过去。
修法:补丁 0001-hardcode-version-no-git-dep.patch,把版本硬编码,直接 file(WRITE) 生成 version-git.h:
set(MBPOLL_VERSION_MAJOR 1)
set(MBPOLL_VERSION_MINOR 5)
set(MBPOLL_VERSION_PATCH 4)
set(MBPOLL_VERSION_STRING "${MBPOLL_VERSION_MAJOR}.${MBPOLL_VERSION_MINOR}.${MBPOLL_VERSION_PATCH}")
file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/version-git.h "#define VERSION \"${MBPOLL_VERSION_STRING}\"\n")
file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/version-git.h "#define VERSION_SHORT \"${MBPOLL_VERSION_STRING}\"\n")
# ... VERSION_TINY / VERSION_MAJOR / VERSION_MINOR / VERSION_PATCH / VERSION_SHA1
这类"构建可重现性"补丁是积分赛里最常见的一类,凡是上游 CMake/Makefile 里出现 git describe、git rev-parse,提前打掉。
坑 2:调用方用了依赖库还没有的 API
现象:libmodbus 编好了,mbpoll 编译报 MODBUS_QUIRK_MAX_SLAVE、MODBUS_QUIRK_REPLY_TO_BROADCAST、modbus_enable_quirks 未声明。
根因:mbpoll 1.5.4 的 -Q / -X 选项调用 libmodbus 的 quirks API,这套 API 是 3.1.7 之后的 3.1.x 才加的(3.1.12 确认有),我们能拿到的带 configure 的发布包只到 3.1.7。典型的"调用方比依赖新"的版本错位。
为什么不能 #ifdef:quirks 是 enum 值和函数,不是宏,#ifdef MODBUS_QUIRK_MAX_SLAVE 探测不到。
修法:补丁 0002-make-libmodbus-quirks-optional.patch,用自定义宏守卫这段代码:
#if defined(MBPOLL_ENABLE_LIBMODBUS_QUIRKS)
if (ctx.bEnableMaxSlaveQuirk || ctx.bEnableReplyToBroadcastQuirk) {
int iQuirks = 0;
/* ... modbus_enable_quirks(ctx.xBus, iQuirks) ... */
}
#endif
本构建不定义该宏,-Q / -X 可以解析但是空操作。这是一个明确记录在 notes.md 和 PR 里的已知限制,不影响核心的 Modbus 读写。评审最反感的是"偷偷砍功能",写清楚了就是合理取舍。
坑 3:musl 工具链没有 linux/serial.h
现象:编 libmodbus 的 modbus-rtu.c 报 linux/serial.h: No such file or directory。
根因:OHOS 工具链基于 musl,不带 Linux 内核 UAPI 头。modbus-rtu.c 在 HAVE_DECL_TIOCSRS485 下为 RS485 的 ioctl 包含了这个头,用到 struct serial_rs485 和 SER_RS485_* 常量。
修法:这个结构体是内核 ABI,定义极其稳定,配方里直接 save() 一个最小 shim,编 libmodbus 时 -I 进去:
_LINUX_SERIAL_H = """\
#ifndef _LINUX_SERIAL_H
#define _LINUX_SERIAL_H
#include <stdint.h>
struct serial_rs485 {
uint32_t flags;
uint32_t delay_rts_before_send;
uint32_t delay_rts_after_send;
uint32_t padding[5];
};
#define SER_RS485_ENABLED (1u << 0)
#define SER_RS485_RTS_ON_SEND (1u << 1)
#define SER_RS485_RTS_AFTER_SEND (1u << 2)
#define SER_RS485_RX_DURING_TX (1u << 4)
#define SER_RS485_TERMINATE_BUS (1u << 5)
#endif
"""
shim = os.path.join(self.build_folder, "include_shim")
save(self, os.path.join(shim, "linux", "serial.h"), _LINUX_SERIAL_H)
os.environ["CFLAGS"] = "-I{} -O2".format(shim)
用 shim 而不是把 HAVE_DECL_TIOCSRS485 关掉,是为了保留 RS485 功能,只补缺失的声明,不改行为。
坑 4:老 config.guess 不认识 HarmonyOS
风险:这是知识库 E007 记录的坑,之前在其它 autotools 库上踩过:本地容器 configure 一切正常,CI worker 上 config.guess 报无法识别平台。这次在首次提交就做了规避,所以本 PR 的 CI 没有为它失败过。
根因:就是第二节说的 uname 差异。libmodbus 3.1.7 自带的 config.guess 早于 OpenHarmony,在 uname -s 返回 HarmonyOS 的 worker 上会识别失败。本地容器 uname 是 Linux,所以本地永远复现不了。
修法:显式传三元组,让 configure 根本不去调 config.guess:
arch_cpu = "aarch64" if str(self.settings.arch).startswith("arm") else str(self.settings.arch)
triplet = "{}-unknown-linux-gnu".format(arch_cpu)
self.run('./configure --disable-shared --enable-static --prefix="{}" '
'--build={t} --host={t} --quiet'.format(lm_prefix, t=triplet), cwd=lm_src)
这里有个细节:--build 和 --host 传同一个值,configure 会当成原生构建而不是交叉构建,不会去找 aarch64-unknown-linux-gnu-gcc 这种带前缀的工具。aarch64-unknown-linux-gnu 是标准三元组,老 config.sub 校验能过。另一条路是替换整份带 OHOS 支持的 config.guess/config.sub(知识库 E007),对只有一个子项目的场景,传三元组更轻。
坑 5:HMDFS 上 config.status 建目录后自己没写权限
风险:这是知识库 E011 记录的坑,同样是首版配方就预先处理、本 PR 未在 CI 上实际触发。此前在其它 autotools 库的 CI 日志里,它表现为 ./config.status: line NNN: ./confXXXXXX/subs1.awk: Permission denied,紧接着 could not setup config files machinery。
根因:autoconf 生成的 config.status 用 umask 077 && mktemp -d ./confXXXXXX 建临时目录(mode 700)。CI worker 的工作目录在 HMDFS 上,实测表现是目录 owner 对自己 mode 700 的目录没有写权限。本地容器是普通文件系统,永远不复现。
修法:configure 跑之前把 umask 077 / umask 000 全改成 umask 022:
def _relax_umask(path):
with open(path) as f:
content = f.read()
content = content.replace("umask 077", "umask 022").replace("umask 000", "umask 022")
with open(path, "w") as f:
f.write(content)
for fn in ("configure", "config.status"):
p = os.path.join(lm_src, fn)
if os.path.isfile(p):
_relax_umask(p)
补充:mbpoll 用 022 在 CI worker 和 HAD 真机复测都通过了。但笔者在另一台 devbox 真机上适配别的库时遇到过更极端的情况:HMDFS 上新建文件的 owner uid 与进程 uid 不一致,进程靠 group 权限访问,022 也不够,得 002 保留 group 写权限。遇到 022 仍报 Permission denied 时可以往这个方向查。
坑 6:环境变量泄漏进主项目
这个不是报错,是差点埋雷。编 libmodbus 时我通过 os.environ 设了 CC 和 CFLAGS=-I<shim> -O2。如果不还原,后面 mbpoll 的 CMake 构建会继承这套 CFLAGS,shim 的 -I 混进主项目,将来查问题会非常迷惑。
saved = {k: os.environ.get(k) for k in ("CC", "CFLAGS")}
os.environ["CC"] = cc
os.environ["CFLAGS"] = "-I{} -O2".format(shim)
try:
self.run("./configure ...", cwd=lm_src)
self.run("make -j2", cwd=lm_src)
self.run("make install", cwd=lm_src)
finally:
for key, prev in saved.items():
if prev is None:
os.environ.pop(key, None)
else:
os.environ[key] = prev
顺带一提 cc 的来源:self.conf.get("tools.build:compiler_executables", check_type=dict),从 Conan profile 里取,而不是读 shell 的 $CC。这是仓库规则 R33。
坑 7:两个小的 CMake 开关
-
MBPOLL_CUSTOM_RTS_GPIO=OFF:上游可选依赖 piduino 做 GPIO 控制 RS485 的 RTS 引脚,OHOS PC 没有这套设施,关掉。 -
CMAKE_SKIP_RPATH=ON:本仓构建环境下 cmake 在 install 阶段做 RPATH 重链接会在CMakeRelink.dir上失败。我们静态链接不需要 RPATH,直接跳过。
ounter(counterh2六、测试:拿真数据,不编数据
PR 模板要填"上游测试用例通过率"。我的原则是:通过率必须来自实跑,分母必须是上游总数。
6.1 上游 33 个单元测试本地实跑
配方本身 BUILD_TESTING=OFF(上游测试没接进 CI 门禁),在构建容器里单独打开跑:
| 测试程序 | 计数方式 | 通过 / 总数 | 覆盖内容 |
|---|---|---|---|
| test_utils.c | 10 个测试函数 | 10 / 10 | iGetIntList 整数列表解析,lSwapLong / fSwapFloat 字交换 |
| test_serial.c | 程序自计数 g_tests_run | 23 / 23 | 串口参数枚举转字符串(flow / databits / stopbits / parity) |
| 合计 | 33 / 33(100%) |
$ ./bin/test_utils → All tests passed. (exit 0)
$ ./bin/test_serial → Tests run: 23, Tests failed: 0, ALL TESTS PASSED (exit 0)
$ ctest → 100% tests passed, 0 tests failed out of 2
6.2 反向验证:确认不是假绿
"全过"最怕的是 harness 根本没在检查。我把 test_serial 换成一个 exit 1 的桩重跑 ctest,得到 test_serial (Failed),说明 CTest 真能抓到失败。这一步只要 30 秒,建议每个库都做。
6.3 test_package 烟雾测试
test_package 跑打好包的二进制,mbpoll -V 输出版本号并用正则校验:
#!/data/service/hnp/bin/bash
set -eo pipefail
MBPOLL="${1:?usage: test.sh <mbpoll binary>}"
"$MBPOLL" -V 2>&1 | head -3
"$MBPOLL" -V 2>&1 | grep -qE "[0-9]+\.[0-9]+"
echo "[ok] mbpoll executable runs and reports its version"
有个平台细节:OHOS 的 /system/bin/sh 是 mksh,不能直接执行 ELF,所以 test_package 的 conanfile 用 hnp 的 bash 驱动脚本,二进制路径从 self.dependencies["mbpoll"].package_folder 拼全路径,不依赖 PATH。
6.4 二进制安全检查
file bin/mbpoll → ELF, arm64, dynamic (/lib/ld-musl-aarch64.so.1)
readelf -d → NEEDED: libc.so (libmodbus 已静态链入)
readelf -h → Type: DYN (PIE)
readelf -l → GNU_STACK(NX)+ GNU_RELRO
PIE、NX、RELRO 齐全。
6.5 真机复测
2026-07-19 在 HarmonyOS HAD 206.1.0 真机(OHOS SDK clang 15.0.4)上 conan create + test_package 原生跑通。这一步的意义在于:容器里的 hnp clang 是"同源"但不完全等价于真机 SDK clang,真机跑一遍才能说"适配完成"。

HarmonyOS HAD 真机上运行打包后的 mbpoll:-V 输出 1.5.4,readelf 仅见 libc.so,test.sh 烟雾测试通过
图 2:真机复测终端记录(按 notes.md 中的实测输出重绘)
ounter(counterh2七、CI 门禁与 PR 流转:一条真实的时间线
配方写完只是一半,PR 流转是另一半。这条 PR 的时间线很有代表性:
| 时间 | 事件 | 说明 |
|---|---|---|
| 07-15 | 提交 PR,机器人给出变更摘要 + 代码审查(2 个 P3) | 未使用的 import、set -e 少了 -u,均为规范项 |
| 07-15 | CI 排队 | 一直没有 worker 领取 |
| 07-16 | 机器人提示"此 PR 从未触发 CI,自动重新排队" | 依旧没跑 |
| 07-17 | 手动评论 /rebuild | 立刻被 worker CI-022 领取,首次 CI 通过(#5128) |
| 07-18 | 追加 E215 知识条目(路径 B),CI 再次通过,机器人二次审查覆盖了新增的知识文件 | |
| 07-22 | 一次 CI 失败于 git-clone 步骤 | 纯 worker 基础设施问题,与配方无关 |
| 07-23 | /rebuild 被门禁拦下:"审核未通过 0/4,测试未通过 0/1" | 人工审核前置于 CI 触发 |
| 07-24 | 门禁放行,CI 通过(#9962,CI-007);上午一次 checkout-pr 抖动(#9993)后,REL-010 跑发布流水线 #320:conan-upload + sign-artifacts 全绿 | 合入 main,制品仓可用 |
几条经验:
-
CI 排队超过一天不动,直接评论
/rebuild。 排队系统会丢任务,等是等不来的。 -
失败先看失败在哪一步。 失败在
git-clone、checkout-pr、worker-prep的,是基础设施抖动,等下一次 rebuild 即可;只有conan-build-test失败才是配方的问题。机器人的"失败诊断"分类经常是"未知",要点进完整日志看。 -
机器人的状态评论是原地改写的(多个 PR 观察到的现象)。 同一条评论会被后续构建反复更新,"失败"不是终态,别急着改代码。
-
人工审核是 CI 的前置门禁。 4 位审核 + 1 位测试都要打勾,之后 CI 才会自动触发,所以 PR 描述要把"为什么这样做"写清楚,审核人不用追着问。

ohpcd-robot 的 CI 校验通过评论:构建 #9962,L0/L1 门禁与 test_package 全部通过
图 3:CI 校验通过评论(按 PR #2310 评论原文重绘)
ounter(counterh2八、知识沉淀:从一次适配到一条可复用的模式
积分赛"路径 B(贡献创新)"鼓励把适配经验沉淀为知识图谱条目。这次沉淀的是 E215 — vendored/bundled 依赖的构建模式:
-
触发条件:库依赖某个未发布到制品仓、仓库内也无配方的库,但可以拿到其源码。
-
推荐方案:
build()内先把子项目configure --disable-shared --enable-static --build=<triplet>编成静态库,make install到build_folder/<dep>-root的 staging 目录;主库通过-I/-L或PKG_CONFIG_PATH指向 staging。 -
禁止做法:假设 worker 系统里有这个库;把 vendored 依赖编成
.so动态链接(要额外签名、要LD_LIBRARY_PATH);手工 copy.o/.a进产物。 -
验证方式:
readelf -d <产物> | grep NEEDED只应看到libc.so之类的系统库。
同一模式覆盖了 mbpoll(libmodbus)、logrotate(popt)、log4cxx(apr + apr-util + expat)、tmate(libssh + msgpack + mbedtls + ncurses)四个库的适配,一条经验多次复用,比多适配一个库更值。
ounter(counterh2九、复盘总结
回头看,mbpoll 本身没有一行代码需要为鸿蒙"改逻辑",所有工作都在构建层和依赖层。这也是 PC 三方库适配的常态:难点不在目标库,在它周围的生态缝隙。
给后来者的 checklist:
-
[ ] 依赖是否真在制品仓?看能不能
conan install,别信status: built -
[ ] 源码包里有没有
git describe、git rev-parse?提前打补丁硬编码版本 -
[ ] 依赖版本能否满足调用方 API?enum/函数不能
#ifdef,用自定义宏守卫并记录限制 -
[ ] musl 缺哪些内核头?能用最小 shim 补声明的,不要关功能
-
[ ] 有 autotools 子项目?显式
--build/--host三元组,绕开老config.guess -
[ ] 先在容器验证,再想一遍"CI worker 的 uname 和 HMDFS 会不会让这一步分叉"
-
[ ]
umask 077改022(E011) -
[ ] 子项目的 CC/CFLAGS 用 try/finally 还原,别泄漏进主项目
-
[ ] 上游测试实跑取数,分母用上游总数,再做一次反向验证防假绿
-
[ ]
readelf -d看 NEEDED,readelf -h/-l看 PIE/NX/RELRO -
[ ] CI 排队超一天就
/rebuild;失败先看是哪一步 -
[ ] 能沉淀成通用模式的,写成知识条目
ounter(counterh2附:PR 文件清单
archives/m/mbpoll/
├── README.md # 适配说明
├── commands.json # 向制品仓注册 mbpoll 命令行工具
├── manifest.yaml # 软件级 manifest
└── 1.5.4/
├── conanfile.py # 配方:vendor libmodbus 静态编译 + CMake 构建 mbpoll
├── conandata.yml # 两个源 + 两枚补丁
├── manifest.yaml # 版本级 manifest,含真机复测记录
├── notes.md # 适配笔记、测试实跑记录、已知限制
├── patches/
│ ├── 0001-hardcode-version-no-git-dep.patch
│ └── 0002-make-libmodbus-quirks-optional.patch
└── test_package/
├── conanfile.py # 跑打包后的二进制
├── test.sh # mbpoll -V 烟雾测试
└── MANIFEST.yml # 上游测试声明(33 个断言)
knowledge/graph/draft/
├── E215-draft-9E9A.kv # 知识条目(结构化)
└── E215-draft-9E9A.md # 知识条目(说明文档)
PR 链接:https://gitcode.com/OpenHarmonyPCDeveloper/build_in_harmonyos/merge_requests/2310 上游仓库:https://github.com/epsilonrt/mbpoll
更多推荐


所有评论(0)