欢迎加入开源鸿蒙PC社区: https://harmonypc.csdn.net/

欢迎在PC社区平台申请新建项目:https://atomgit.com/OpenHarmonyPCDeveloper

Zeek 8.2.1成功移植至鸿蒙PC(aarch64)

项值
适配对象Zeek 8.2.1(开源网络流量分析引擎)
平台鸿蒙 PC:HUAWEI MateBook Pro(HAD-W32)/ OpenHarmony-6.1.0.115 / aarch64
工具链clang 15.0.4 + libc++ / C++17 / CMake 4.1.2 / Conan 2.29.1
配方仓库build_in_harmonyos(AtomGit)
PR#12038(已合并,2026-09-29)

摘要:把 Zeek 8.2.1 搬到鸿蒙 PC(aarch64)要过四道坎:私有 host 生成器工具链(bifcl/binpac/gen-zam 先编译再产码)、libc++ 15 与 musl 的标准库缺口(std::pmr / std::ranges / fts)、CMake 4.1.2 交叉模式 ALIAS 目标名不展开、以及构建形态裁剪后上游测试链路的隐性断裂。最终:76 个可移植补丁 + 2 个 shim(零平台宏)解决 10 类平台差异;上游可运行单测子集 ctest broker 26/26;btest 集成套件 285 项因三项环境限制 N/A(work phase 抽样与 Baseline 一致,如实标注);消费者测试在 CI 实跑 1/4(其余 3 项走文档化降级路径)、在鸿蒙 PC 真机以修复后测试向量并加 -C(忽略无效校验和)回放 4/4;经历 3 轮 CI(1 红 2 绿)后 PR 合入 main 并发布制品,随 PR 沉淀 6 条知识草稿。

开场定性:Zeek 这类"编译期生成代码 + 脚本语言运行时 + 用户态分析器"的 C++ 系统,移植的真实工作量不在 CMake 配置,而在标准库与构建工具链的隐性契约——每一处报错背后都藏着一个"上游从未在非 glibc/非完整标准库环境验证过"的假设。这篇文章按适配顺序还原全过程,所有数字均可在仓库与 CI 记录中溯源。

诚实声明(先读):

  1. 本 PR 采用最小构建形态(Spicy 分析器 DSL、JavaScript、zeromq 集群后端、Python 工具链全部关闭);Spicy-on 全量形态在 HILTI 的 std::hash<std::filesystem::path> 标准库缺口处止损,转后续 PR——"适配完成"仅指本形态。
  2. btest 集成套件(285 项)在 OHOS 本地未全量执行,原因逐项列出(见 4.1);已执行部分的证据(work phase 抽样 7/7 与 Baseline 一致)如实标注边界。
  3. 消费者测试 4 用例的"4/4"发生在鸿蒙 PC 真机 + btest 标准环境 + 修复后的测试向量 + -C(忽略无效校验和)(4.3 节分层根因);CI 上 Spicy-off 形态实跑 1/4、其余 3 项走文档化降级跳过。两个口径都不含糊。

一、背景:为什么值得做

Zeek 是最广泛使用的开源网络流量分析引擎:它把原始 pcap/实时流量解析成结构化事件日志(conn/http/dns/ssl/…),供 SIEM 与安全分析消费。安全分析工具链是任何桌面/PC 生态的刚需——鸿蒙 PC 作为新平台,三方安全分析库的缺位意味着这类工作流只能在其他平台上做,再人工搬运结果。

选 Zeek 做路径C(高难度挑战)适配,理由三层:

  1. 生态价值:流量分析是安全工具链的核心节点,下游(SIEM 接入、合规审计、研究复现)依赖它的日志格式稳定性;
  2. 真实先例:上游社区本身就在多平台(Linux/FreeBSD/macOS)维护,说明代码基础具备跨平台潜力,缺的只是 OHOS 这一支的工程工作;
  3. 难度覆盖:它同时具备四类典型高难度特征——私有构建工具链(三个 host 生成器)、巨大依赖链与源码树规模(auxil/spicy、auxil/broker、3rdparty 三个子模块合入)、用户态"类特权"系统调用密集(pcap 抓包、kqueue 移植层、fiber 协程)、以及测试成本极高(285 项集成测试 + 1824 个辅助脚本)。一个库把适配方法论的各个面都逼出来了。

二、环境与差异前置

环境表(当事机器实测,命令附后):

项实测值测量命令
设备HUAWEI MateBook Pro(HAD-W32)param get const.product.model
系统OpenHarmony-6.1.0.115param get const.ohos.fullname
内核HongMeng Kernel 1.12.0uname -a
架构aarch64uname -m
编译器clang 15.0.4 + libc++,C++17conan profile show
构建工具CMake 4.1.2配方构建日志
包管理Conan 2.29.1(OHOS 社区适配版)conan --version
上游源https://download.zeek.org/zeek-8.2.1.tar.gz(HEAD 200,国内可访问)curl -sI
源码 sha256a8067c75cc89bef4b58019230434a90073671a7cabfcf7ac616ac872a40a2eddconandata.yml

差异点总表(每个差异点在第三节对应一个坑位):

#差异点上游假设鸿蒙 PC 实际情况对应坑位
1生成器工具链host 与 target 工具链一致bifcl/binpac/gen-zam 须先针对 host 编译;CMake 4.1.2 交叉模式下 ::ALIAS 目标名在 add_custom_command 中不展开坑1
2std::ranges完整 C++20 标准库libc++ 15.0.4 无 views::transform 等算法集;47 个文件 83+ 使用点坑2
3std::pmr / memory_resourceC++17 标准头可用libc++ 15 无 <memory_resource> 标准头(experimental 只声明未定义);broker 37 处使用,13 项测试 SEGFAULT坑3
4fts.hBSD/glibc 目录树 APIOHOS musl sysroot 无 fts(3),zeekygen 初始化即 fatal坑4
5construct_at 聚合初始化C++20 语言特性完整支持该 clang/libc++ 组合不支持聚合体的 std::construct_at坑5
6glibc 专属 APIglibc 生态POLLRDHUP 等宏/符号缺失,需能力探测 + POSIX 等价坑6
7/tmp 可写系统临时目录可写HMDFS /tmp 只读,且上游临时文件命名不认 TMPDIR坑7
8pthread 取消pthread_cancel 可用OHOS 不支持,需优雅退出协议 + weak shim坑8
9构建形态裁剪的副作用默认 base 脚本与全部分析器共存DISABLE_SPICY 下 base 默认上下文仍加载 igmp → 初始化错误(连锁反应见 4.3 与 4.5)坑9
10测试向量自校验测试向量本身正确自研确定性 pcap 生成器两层校验和缺陷:IP 头只算半个头 + TCP 段校验和=0(4.3 节分层根因)坑10

三、适配过程

侦察(动手前):依赖发布预检——libpcap/1.10.6、openssl/3.5.8.1、zlib/1.3.1(requires)与 flex/2.6.4、bison/3.8.2(tool_requires)均已发布制品仓,无需先适配依赖;构建系统为 CMake(含 host 生成器两步构建);测试策略定为"上游可运行子集实跑 + 消费者测试 + 分层如实申报"。

依赖树:

zeek/8.2.1
├── requires(运行期)
│   ├── libpcap/1.10.6      # pcap 抓包/回放
│   ├── openssl/3.5.8.1     # TLS 解析
│   └── zlib/1.3.1
├── tool_requires(构建期)
│   ├── flex/2.6.4          # 词法生成
│   └── bison/3.8.2         # 语法生成
└── 源码树内嵌(子模块合入,官方 tarball 含符号链接环)
    ├── auxil/spicy         # Spicy DSL 分析器(本形态关闭)
    ├── auxil/broker        # 消息层(pmr 重灾区,坑3)
    └── 3rdparty            # hilti-runtime / fiber / kqueue 等

坑1|CMake ALIAS 目标名不展开(Error 127)

  • 现象:交叉 configure 后 make 阶段,三个生成器步骤报 Error 127(命令未找到),命令行里赫然出现字面量 Zeek::BifCl。
  • 定位:对比 host 构建与交叉构建的 CMake 展开结果,确认 add_custom_command(COMMAND Zeek::BifCl ...) 中 ::ALIAS 目标名在 CMake 4.1.2 交叉模式下未被展开为可执行文件路径。定位耗时不长(报错信息自带线索),但一度误以为是工具链 PATH 问题,排查了 PATH/SDK 路径后才回到 CMake 语义本身。
  • 方案:三个 cmake 文件(BifCl/BinPAC/Gen-ZAM,补丁 0021–0023)统一改为生成器表达式 $<TARGET_FILE:Zeek::BifCl>(可移植,零平台宏)。
  • 经验:交叉编译下"目标名出现在最终命令里"= CMake 展开缺陷,别在 PATH 上浪费时间;$<TARGET_FILE:...> 是 ALIAS 场景的通用解。
  • 入档:本案已入档知识草稿 E431(错误签名:Error 127 + 命令行含 :: ALIAS 字面量),条目见第五节。

坑2|std::ranges 整批缺失(47 文件,83+ 使用点)

  • 现象:核心编译大面积报错,no member named 'views' in namespace 'std' 一族。
  • 定位:grep 全源码统计使用点 = 47 文件 83+ 处;逐一确认 libc++ 15.0.4 的 <ranges> 只提供了视图骨架,views::transform 等算法视图缺失。
  • 方案:全部改写为经典 STL 等价(循环/std::transform 迭代器版/std::accumulate),0024–0075 共 52 个 src/ 补丁为主体,broker 侧散布在 0006/0010/0011。
  • 误判(自曝):C 数组站点(broker 0006/0010/0011,如 std::begin(handshake_states) 作用于静态数组)最初被当成容器站点照抄改写——C 数组场景 begin/end 返回指针,个别站点显式指定迭代器类型后才编译通过。教训:ranges→STL 改写不是机械替换,数组/容器要分开验证。
  • 入档:本案已入档知识草稿 E430(错误签名:no member named 'views' in namespace 'std',含 C 数组派生陷阱对照组),条目见第五节。

坑3|std::pmr / <memory_resource> 缺失(13 项测试 SEGFAULT)

  • 现象:broker 消息层 13 项单元测试全部 SEGFAULT(不是断言失败,是段错误)。
  • 定位:broker 37 处使用 std::pmr::polymorphic_allocator / monotonic_buffer_resource;OHOS libc++ 15 的 <memory_resource> 标准头不存在,<experimental/memory_resource> 只有声明没有实现——链接进了"空壳"符号,运行时段错误。这一坑定位最久:段错误表象像堆损坏,排除到"标准库符号缺失"用了半天(先怀疑 fiber 协程栈,再怀疑 pmr 分配器生命周期,最后用符号表比对锁定)。
  • 方案:自写 shim 头 <memory_resource> 经 -I 注入构建路径——复用 SDK experimental 基类接口 + 自实现对齐 bump-pointer 语义的 monotonic_buffer_resource + 补全局资源符号。shim 是 2 个 shims 之一(另一个 pthread_compat,坑8),不进 patches/(注入与 weak 链入方式不同)。
  • 经验:SEGFAULT + "标准库 API 找不到定义"时,先查符号表再怀疑业务逻辑;shim 头方案要求接口与标准逐字对齐,否则 ABI 漂移。
  • 入档:本案已入档知识草稿 E429(错误签名:pmr 相关 SEGFAULT + 符号缺失,含对照组结论),条目见第五节。

坑4|fts.h 缺失(zeekygen 初始化 fatal)

  • 现象:zeekygen(Zeek 类型内省/文档工具)初始化即 fatal:fts.h 找不到。
  • 定位:zeekygen 源码用 fts(3) 递归遍历脚本目录;OHOS sysroot 无 fts(3)。
  • 方案:改写 std::filesystem::recursive_directory_iterator(补丁 0074/0075,zeekygen Target.cc / utils.cc),行为等价、零平台宏。
  • 经验:"目录树 API 缺失"类在 C++17+ 上首选 std::filesystem 替代;改写时对齐 fts 的遍历语义(顺序/错误处理),zeekygen 的用法是简单遍历,无差异。
  • 入档:本案已入档知识草稿 E432(错误签名:fts.h fatal,含 std::filesystem 改写对照),条目见第五节。

坑5|construct_at 聚合初始化不支持

  • 现象:src/script_opt 编译错误:聚合体类型的 std::construct_at 初始化失败。
  • 定位:CallInfo/DispatchInfo 是聚合体,上游代码走 construct_at 的聚合初始化路径;该 clang/libc++ 组合不支持。
  • 方案:给聚合体补显式构造(补丁 0057–0059),construct_at 走构造路径。
  • 经验:"C++20 特性部分支持"类问题,别试图让特性工作——显式降级到 C++17 语义(显式构造)立即收敛,比追查编译器/标准库行为快得多。
  • 入档:本案已入档知识草稿 E433(错误签名:construct_at 聚合初始化失败,含显式构造对照),条目见第五节。

坑6|glibc 专属 API(POLLRDHUP 一族)

  • 现象:多个文件报 POLLRDHUP 等 glibc 专属宏/符号缺失。
  • 方案:三策略组合——能力探测宏(CMake 检测后定义)、POSIX 等价(epoll/poll 边缘场景按"缺失=0"语义降级处理)、其余可移植改写;是 0024–0075 共 52 个 src/ 补丁的主体构成之一。
  • 经验:musl 目标上不要打 glibc 补丁;每个 glibc 专属符号单独判定"探测/等价/改写"三选一,判据是 POSIX 是否提供等价语义。

坑7|/tmp 只读 + TMPDIR 不识别(broker.backend)

  • 现象:broker.backend 单测失败(无法创建临时文件);一切硬编码 /tmp 的临时文件逻辑在 HMDFS 上全部失败(/tmp 只读是平台事实)。
  • 定位:两层——平台 /tmp 只读;上游 broker 的 make_temp_file_name POSIX 分支硬编码 /tmp 前缀且不读 TMPDIR。
  • 方案:补丁 0003(libbroker/detail/filesystem.cc):优先 ::getenv("TMPDIR")(空则回退 /tmp)+ mkstemp;测试运行注入 TMPDIR=<可写目录>。未设 TMPDIR 时行为与上游逐字一致。
  • 经验:"临时目录"必须当可配置输入;TMPDIR 是 POSIX 惯例,补上这一处让测试在任何只读 /tmp 环境可运行。
  • 入档:本案已入档知识草稿 E434(错误签名:临时文件创建失败 + /tmp 只读,含 TMPDIR 可移植改写对照),条目见第五节。

坑8|pthread_cancel 不可用

  • 现象:线程管理代码使用 pthread_cancel,OHOS 不支持(链接/运行期失败)。
  • 方案:优雅退出协议(标志位 + join)替代强制取消;weak 符号 shim(pthread_compat,2 个 shims 之二)兜底不可改代码的链接兼容。
  • 经验:"线程取消"类问题只有协作式退出是跨平台可移植路径;weak shim 留给无法修改的第三方调用点。

坑9|构建形态裁剪的副作用:igmp 初始化错误链(坑中之坑)

  • 现象:DISABLE_SPICY 形态下,zeek -r / -b 每次运行都在初始化报 error ... Failed to register IGMP Spicy analyzer.;不设 ZEEK_ALLOW_INIT_ERRORS=1 则直接 fatal,整个进程起不来。
  • 定位:grep 源树确认加载链:base/init-bare.zeek:6750 @load base/packet-protocols → base/packet-protocols/__load__.zeek:24 @load base/packet-protocols/igmp——默认上下文无条件加载 igmp,上游脚本对禁-Spicy 构建没有条件守卫。对照实验:零 @load 的平凡脚本同样命中(加载来自默认 init 上下文,与用户脚本无关)。
  • 误判(自曝):最初以为"test-script.zeek 不 @load igmp 就没事",在这个方向上浪费了时间——直到平凡脚本对照实验推翻。教训:报"未注册"类错误先 grep 谁在加载,不要默认是自己的脚本所为。
  • 方案(三层):① 测试侧带 ZEEK_ALLOW_INIT_ERRORS=1 运行(btest.cfg [environment] 标准环境,上游自己的测试惯例);② test.sh 文档化降级路径 (b):命中 igmp fatal 时跳过 pcap 用例并注明、exit 0——CI 实际就是这么过的(4.5 节);③ Spicy-on 全量形态下该错误天然消失(base 上下文正常加载)。
  • 经验:形态裁剪(关闭任何子系统)前必须做默认上下文审计——枚举 base 默认加载链对该子系统的全部引用;这个清单就是降级路径设计、测试申报口径的输入。
  • 备注:此教训写入本 PR notes.md(形态相关,是否升格知识草稿由主编定)。

坑10|测试向量自校验:sample.pcap 的两层校验和缺陷

  • 现象(两阶段):阶段一——真机回放确定性测试 pcap(igmp 链已解决)后零 conn 记录,weird.log 仅 2 条 bad_IP_checksum。阶段二——修复 IP 校验和重新生成后,回放仍无 SNI/HTTP 断言命中(ssl.log/http.log 空、conn 记录为零字节半成品记录 + active_connection_reuse×2),终端出现 find-checksum-offloading 警告:trace 的 TCP 校验和无效。
  • 定位:阶段一——脚本逐包解析 pcap 校验 IP 头校验和,17 包全部无效;生成器 _ip_checksum(hdr[:10]) 只计算头部前 10 字节(ver…proto),IP 头校验和应覆盖完整 20 字节(含 src/dst)。阶段二——TCP 段校验和全为 0,生成器注释 “parsers do not verify it” 对 zeek 不成立:zeek 默认丢弃无效 TCP 校验和的包(除非 -C/ignore_checksums),SSL/HTTP 分析因此收不到 TCP 载荷;UDP(csum=0 合法)不受影响,所以 DNS 断言正常命中。
  • 为什么一直没暴露(分层遮蔽):CI 的 Spicy-off 形态被 igmp 初始化错误触发 test.sh 降级路径 (b) → case2–4 从未实跑;真机不带 btest 标准环境直接 fatal → 跑不到;真机带标准环境后向量 IP 缺陷 → 零 conn;修掉 IP 后向量 TCP 缺陷 → SNI/HTTP 不命中。四层剥离,向量缺陷靠逐包解析回验才逐层暴露。
  • 方案:修复生成器 IP 校验和(_ip_checksum(hdr),覆盖完整 20 字节,本地验证版)+ 回放命令加 -C(zeek 针对 NIC 校验和卸载场景的官方选项,忽略无效校验和)→ 真机回放 4/4 全中(3×P1-CONN + P1-SNI + P1-DNS + P1-HTTP,共 6 行,4.3 节)。TCP 校验和本应在生成器里按 RFC 算对——仓库版修复应走单独 PR,两层一起修并给 test.sh 同步加 -C(本 PR 已合并,不动)。
  • 经验:测试向量本身需要测试——确定性生成器必须配独立解析回验(校验和/格式),否则固定 sha256 只证明"每次都生成同样的错误字节";生成器自带注释(“parsers do not verify it”)是向量的隐含假设,假设要在目标引擎上复核。
  • 备注:此教训写入本 PR notes.md。

四、验证(分层,禁止相加)

口径声明:以下各层分别统计、分别陈述,不做相加/改名/拼接。“上游单测”“消费者测试”"btest 集成套件"是三个互不包含的集合,本文所有数字都挂在各自层内。

4.1 上游测试实跑(R51 三步法台账)

清点(上游测试资产):

测试集规模来源
btest 集成套件285 个 .test + 2 个 .zeek 独立项 = 287 注册;另有 1824 个辅助 .zeek(被 .test 引用,不计独立用例)PR 正文口径(本机 find 复核 .test=285,已排除 btest .tmp 执行残留;与审查方实测一致)
ctest 单元测试35 = 26 broker.* + 8 python-* + 1 其它CTestTestfile 清点
冒烟1(zeek --version)—

实跑(可运行环境):

测试集结果说明
ctest broker.*26/26(100%)构建树本地实跑;含 13 项 pmr SEGFAULT 恢复(坑3)+ broker.backend(坑7);此前 25/26 的失败项经补丁 0003 修复
ctest python-*0/8(N/A)形态原因:Python 工具链关闭,本形态不存在该 8 项——不适用,非失败
ctest 其它 1 项未单独计入不属本形态可运行申报范围
冒烟1/1zeek version 8.2.1,exit 0
btest 285 项N/A(OHOS 本地未全量执行)三项具体技术原因见下
btest 抽样(core.pppoe,r-only 形态)work phase 7/7 conn 记录与 Baseline 逐字段一致btest 标准环境 + kill wrapper 早杀;#close 已写、日志完整;边界:抽样,非全量

btest 未全量执行的三项具体技术原因(不是"没环境"一句话):

  1. 形态:189 个 zeek -b 类项需完整 base 上下文 → Spicy-off 命中 igmp 初始化错误(坑9),需 Spicy-on 全量构建解除;
  2. 退出路径挂死 + btest 无 per-test timeout:本机(OHOS)zeek 进程 work phase 完成后在退出路径挂起(main@FUTEX,SIGTERM 无效),btest 无单测超时 → 单项挂起整 run 停摆(09-24 全量试跑实证);
  3. HMDFS /tmp 只读:btest 默认临时目录不可写(已用 TMPDIR 重定向解决,属可解决项,列此完整)。

失败模式分类:适配期间出现的全部失败均属"平台缺口"类(pmr / ranges / fts / pthread / /tmp),零"适配回归"类(上游能过、适配后不能过的情况不存在)。

证据已入仓可复现:test-report.md(R51 回填)、notes.md P1–P10、Baseline 对比记录、.ci-result.json(W3 日志 10322 行 + sha256 哈希)。

4.2 形态分类与留证(本 PR 保留什么、裁掉什么)

  • 保留(核心价值链):pcap 解析、conn/http/dns/ssl 等核心协议分析器、Zeek 脚本解释器、bifs(二进制接口函数)、broker 消息层(库形式入包)。
  • 裁掉:Spicy DSL 分析器链(auxil/spicy + HILTI runtime)、JavaScript 引擎、zeromq 集群后端、zeekctl/zkg/zeek-client Python 工具链。
  • 为什么不裁进 PR 而留后手:Spicy-on 全量在 HILTI std::hash<std::filesystem::path> 标准库缺口阻断(2 文件,hilti 0.32,上游 2026-07-20 状态),修复范围超出本 PR 边界 → 转单独 PR;JS/zeromq/Python 工具链非核心分析链路所需,且 CI worker 与目标环境无 Python Development 组件(CI 第 1 轮红的直接原因)。
  • 留证(不冒充全量):以上全部在 conanfile.py(DISABLE_* / INSTALL_* 标志)与 PR 正文"已知限制"声明;igmp 初始化错误链(坑9)正是 Spicy-off 形态边界的运行时证据——形态边界是真实、可复现的,不是口头声明。

4.3 消费者测试(L2:真实 API + 结果断言)

设计(test_package,4 用例,非 L1 空壳):

用例断言内容级别
case 1zeek --version 输出含 zeek version 8.2.1L1(版本断言,单独不能宣称功能完成)
case 2pcap 回放产出 3 条 conn 记录(tcp 41337→80 / tcp 41338→443 / udp 5353→53)L2(真实输入 + 事件结果)
case 3TLS ClientHello SNI 事件 = zeek.example.comL2
case 4DNS 查询事件 + HTTP 请求事件(GET /hello)L2

测试向量:make_sample_pcap.py 确定性生成(17 包、3 条流、固定地址/端口/时间戳,sha256 钉死——仓库版 69e41219…,本地验证版(IP 校验和修复)32f0e8c0…),仓库不存二进制 pcap(脚本是提交产物,运行时生成)。test.c 为 C 消费端,链接被测包并断言版本输出(R34:测试实质依赖被测包)。

★ 分层根因(为什么"CI 绿"≠"4/4 实跑过"):

  • 第一层(CI 侧):Spicy-off 形态 → igmp 初始化错误(坑9)→ test.sh 降级路径 (b) 跳过 case2–4 并注明、exit 0 → CI #61047 / #10700 的 “test_package 通过” 实际 = case 1 实跑 + case2–4 跳过。
  • 第二层(测试向量侧 ① IP 校验和):真机带 btest 标准环境(ZEEK_ALLOW_INIT_ERRORS=1)绕过第一层后,回放零 conn 记录 → 逐包校验发现 sample.pcap 生成器的 IP 头校验和缺陷(坑10)。
  • 第三层(测试向量侧 ② TCP 校验和):修复 IP 校验和重新生成后,回放仍无 SNI/HTTP 命中——TCP 段校验和全为 0,zeek 默认丢弃无效校验和包(find-checksum-offloading 警告即证据);回放命令加 -C(忽略无效校验和)后 4/4 全中:3×P1-CONN(41337→80、41338→443、5353→53)+ P1-SNI=zeek.example.com + P1-DNS=zeek.example.com + P1-HTTP=GET /hello,共 6 行输出,conn.log/ssl.log/dns.log/http.log 四日志生成,weird 仅 1 条(DNS_truncated_RR_rdlength_lt_len,向量响应字段标注特性,无害)。

结论:CI 实跑 1/4(其余 3 项走文档化降级跳过,原因在 CI 日志与 test.sh 注释中可见);真机 + btest 标准环境 + 修复后向量 + -C 4/4。case2–4 的"功能断言真实通过"(下图)。
在这里插入图片描述

图1:鸿蒙 PC 真机 zeek pcap 回放——四协议断言全中(证明消费者测试 4/4 真机实跑;不能证明全量形态与全量覆盖)

4.4 产物核验

项值证据
主可执行zeek 20.7 MB(aarch64 ELF)构建树实测 + conan-verify-report.md
包体积conan 包 111 MB;packaging tarball 138 MBnotes.md
安全门禁L4(NX/PIE/RELRO 检查)通过、L5(产物基线)通过CI #61047 / #10700 评论
构建耗时首次手动编译约 2h;conan create 全量约 40 分钟(日志 10322 行,sha256 存档)notes.md + .ci-result.json
版本断言zeek version 8.2.1(exit 0)4.6 命令 3 可复现

4.5 CI 与评审

完整轮次表(失败轮不删):

轮次构建结果说明
1CI-038(task #57541,2026-09-24)红pysubnettree find_package(Python Development) 失败——CI worker HNP Python 无 Development 组件(配方/形态对齐问题,非源码缺陷;非基础设施故障,不作废)
2#61047(2026-09-25 19:22)绿配方对齐修复(commit 4773dad7be)后:conan-build-test + test_package + L0/L1 门禁全过
3#10700(worker OpenHarmonyPCDeveloper-REL-037,2026-09-29)绿合并后发布流水线 9 步全 ✅(含 conan-setup / conan-build-test / conan-upload / sign-artifacts / cleanup 等,完整步骤清单见 CI 页),Conan test_package 通过、L0 结构完整性通过、L1 测试执行验证通过

检视记录:检视意见(含两轮 FAIL 判定与行级意见)逐条在讨论串内闭环,代表性三条:

  1. 测试表口径:上游 btest 数按审查方实测 285 申报,2 个 .zeek 独立项(af_packet.plugin、core.pppoe-over-qinq)在说明列单列,不并入 N;
  2. 变更范围:.gitignore 的例外块属框架范畴 → 整块还原,PR 范围收敛为 archives/ + knowledge/;
  3. 全量测试本地可执行性:逐条答复——ctest 26/26 本地实跑;btest 285 不能全量本地执行(三项硬阻塞 + 抽样 7/7 证据);消费者测试 CI 1/4 实跑 + 真机 4/4(即 4.3 节分层根因,真机口径 = 修复后向量 + -C)。

合并记录:PR #12038 合入 main(squash,head 73d66390fd)
在这里插入图片描述

图2:PR #12038 合并页

4.6 复现速查(3 条命令,全部来自实测日志)

#命令 1|全量构建 + 消费者测试门禁(约 40 分钟;与 W3 本地 CI、CI conan-build-test 同源)
cd <build_in_harmonyos 仓库根>
conan create archives/z/zeek/8.2.1/conanfile.py
#期望输出(尾部):conan create exit 0;test_package 执行 test.sh
#(Spicy-off 形态走文档化降级路径 (b):case 1 实跑 + case2-4 跳过并注明,exit 0)

#命令 2|真机回放消费者四协议断言(秒级;修复版生成器见 ~/tmp/s1fix;-C 忽略无效校验和,见 4.3)
cd ~/tmp/s1fix
python3 make_sample_pcap.py sample.pcap
ZEEKPATH="/storage/Users/currentUser/tmp/builds/zeek-8.2.1.work/scripts:/storage/Users/currentUser/tmp/builds/zeek-8.2.1.work/build/scripts" TZ=UTC LC_ALL=C ZEEK_ALLOW_INIT_ERRORS=1 /storage/Users/currentUser/tmp/builds/zeek-8.2.1.work/build/src/zeek -C -r sample.pcap /storage/Users/currentUser/ohpc-contest/zeek-8.2.1/build_in_harmonyos/archives/z/zeek/8.2.1/test_package/test-script.zeek
#期望输出:6 行(实际格式):P1-HTTP=..., GET, /hello / P1-SNI=..., zeek.example.com / P1-DNS=..., zeek.example.com / P1-CONN=...×3(5353/udp、41338/tcp、41337/tcp);CWD 生成 conn.log / ssl.log / dns.log / http.log 四日志
#注意:输出完成后进程退出路径挂起(本机 OHOS 复现,SIGTERM 无效),kill -9 结束

#命令 3|产物版本核验(秒级)
/storage/Users/currentUser/tmp/builds/zeek-8.2.1.work/build/src/zeek --version
#期望输出:zeek version 8.2.1(exit 0)

口径对应:命令 1 → 4.4(conan create 约 40 分钟、日志 10322 行)与 4.5(CI 同源);命令 2 → 4.3(真机 4/4);命令 3 → 4.4(产物 20.7 MB、版本断言)。

五、知识沉淀

编号知识(错误签名摘要)来源坑位复用价值
E429std::pmr / <memory_resource> 缺失(shim 头 backport)坑3本工具链上所有使用 pmr 分配器的 C++ 库
E430std::ranges 算法集缺失(经典 STL 改写 + C 数组派生陷阱)坑2本库 47 文件即现成语料,其它 C++20 库可直接参考
E431CMake ALIAS 目标名交叉不展开($<TARGET_FILE>)坑1所有带私有生成器工具链的 CMake 交叉包
E432fts.h 缺失(std::filesystem 改写)坑4所有使用 fts(3) 的库
E433construct_at 聚合初始化(显式构造降级)坑5C++20 部分支持场景
E434/tmp 只读 + TMPDIR 不识别(可移植改写)坑7所有含临时文件逻辑的库

状态:6 条草稿(12 文件,.kv + .md 配套)已随 PR #12038 入仓,待主编 promote;草稿 source_pr 字段为 11976(首个 PR 号,历史字段)。坑9/坑10 的教训(形态裁剪的默认上下文审计、测试向量自校验)写入本 PR notes.md,是否升格草稿由主编定。

六、FAQ

Q1:为什么是最小构建形态?
A:本 PR 范围是核心分析链路(pcap → 结构化日志)。Spicy-on 全量形态有明确阻断点(HILTI std::hash 标准库缺口,2 文件),转单独 PR——边界写在 conanfile.py 与 PR"已知限制"里。"适配完成"仅对本形态成立,不往外推。

Q2:上游 btest 285 项,本地 0 项,是不是没做?
A:不是"没做",是"不能全量 + 抽样做了 + 原因逐条列出":189 个 -b 类项被形态阻塞(igmp 链,坑9),全集被 btest 无 per-test timeout + 退出路径挂死阻塞,/tmp 只读(已用 TMPDIR 解决,列此完整)。抽样(core.pppoe)的 work phase 输出与上游 Baseline 逐字段一致(7/7),证明适配二进制在可运行环境下输出正确;边界是"抽样,非全量"。全量 btest 需要"Spicy-on 全量构建 + 可写工作目录"的验收机,已写入 PR TODO。

Q3:消费者测试 CI 只实跑 1/4,4/4 在真机——该信哪个?
A:两个都真,口径不同:CI 的 Spicy-off 形态走文档化降级路径 (b)(igmp 初始化错误 → case2–4 跳过并注明),这是 CI 绿的原因;真机在 btest 标准环境下跑 case2–4 断言,还顺带暴露了测试向量的两层校验和缺陷(坑10),修复并加 -C(忽略无效校验和)后 4 项全中。这恰好说明降级路径"跳过了没真测"——真机回放的价值就在补上这一段。

Q4:26/26 单元测试能代表整体质量吗?
A:它代表"本形态下可运行的上游测试子集全部通过"(26 broker.* 为本形态全部可运行单测;8 项 python-* 因形态 N/A)。协议解析正确性另有独立证据:真机回放四协议断言 + btest 抽样 Baseline 一致(4.3 节)。不用单测通过率外推整体功能。

Q5:test.sh 的降级路径 (a)/(b) 是不是"空壳测试"?
A:不是——降级分支只在两个特定前提下触发(host EPERM 限制 / Spicy-off 形态),且每次跳过都必须输出原因(在 CI 日志与 test.sh 注释中可见);case 1 永远实跑,case2–4 是事件级真实断言(P1-* 输出来自 zeek 事件 handler,不是 echo)。R34(测试必须实质依赖被测包)满足:test.c 链接被测包并调用其二进制。

Q6:挂死进程 SIGKILL 收尾,算不算"糊弄测试"?
A:挂死发生在 work phase 完成之后的退出路径;#close 与全部日志文件在挂死前已写出(pilot 与真机回放均验证日志完整)。SIGKILL 只是进程回收,不丢任何测试产物。退出路径挂死在本机 OHOS 的每次 work phase 完成后均复现(pilot 与真机回放一致,main@FUTEX 等待点稳定,根因未定位);CI 中 Spicy-off 形态在 init 阶段即 fatal 退出,未进入 work phase,故 CI 未暴露该现象。

七、总结

7.1 量化盘点

维度数字
补丁76 个(0001–0076)+ 2 个 shims(shim 不含在 76 内,注入方式不同)
平台差异点10 类(§2 差异表,坑1–坑10 一一对应)
构建首次手动约 2h;conan create 全量约 40 分钟(日志 10322 行)
上游测试btest 285 项 N/A(三项原因)+ 抽样 7/7 与 Baseline 一致;ctest 26/26 实跑(8 项 N/A + 1 项不计入);冒烟 1/1
消费者测试CI 1/4 实跑 + 3 项文档化降级;真机(修复后向量 + -C)4/4
CI3 轮(1 红 2 绿),2026-09-29 合入
知识6 条草稿(E429–E434,12 文件)随 PR 入仓

数字包含关系(防误读):76 补丁不含 2 个 shims;btest 287 注册 = 285 个 .test + 2 个 .zeek 独立项;ctest 35 = 26 + 8 + 1;1824 个辅助 .zeek 被 285 个 .test 引用,不计独立用例。

7.2 可复用方法(5 条)

  1. 零平台宏可移植策略:能力宏 / POSIX 等价 / weak shim 三策略组合——补丁干净(无 __OHOS__),未来同步上游零冲突面。
  2. 标准库缺口 shim 头法:缺失的 std 头用 shim 头经 -I 注入 backport,接口必须与标准逐字对齐(E429)。
  3. 私有生成器工具链交叉配方:$<TARGET_FILE:...> 统一替换 ALIAS 目标名(E431)。
  4. 形态裁剪"默认上下文审计":关闭任何子系统前,先枚举 base 默认加载链对它的引用,清单即降级路径设计输入(坑9)。
  5. 测试向量自校验:确定性生成器必须配独立解析回验(校验和/格式),否则固定哈希只固化"同样的错误字节"(坑10)。

7.3 流程 checklist(通用,可直接套用)

  • 适配前依赖发布预检(W0)
  • 语言预检(R47)
  • 构建系统侦察 + host 生成器识别
  • 补丁生成零平台宏策略(能力宏 / 等价 / shim 三选一判定)
  • 消费者测试 L2 化(真实 API + 结果断言,非空壳)
  • 降级路径文档化(每次跳过有原因、CI 可见)
  • CI 修复环(diagnose → 修复 → 本地复验 → push → resume,连续 2 轮同错止损)
  • 知识草稿入档(错误签名 + 根因 + 方案 + 对照组)
  • result.json 终态上报

7.4 后续工作

  1. Spicy-on 全量形态:修复 HILTI std::hash<std::filesystem::path> 缺口(2 文件),开启完整 base 上下文,在可写工作目录验收机跑全量 btest(285 项)——单独 PR。
  2. 测试向量生成器两层校验和修复:仓库版 make_sample_pcap.py 的 IP 头校验和(_ip_checksum(hdr[:10]) → _ip_checksum(hdr))+ TCP 段校验和(按 RC 计算正确 csum,现以 -C 绕过);test.sh 回放命令应同步加 -C(不加则 Spicy-on 形态同样卡在 TCP 校验和层),单独 PR(本文为本地验证版)。
  3. 退出路径挂死:若确认为平台问题,提交平台级反馈(当前仅现象证据,根因待定位)。

参考链接

  • PR:https://atomgit.com/OpenHarmonyPCDeveloper/build_in_harmonyos/merge_requests/12038
  • 配方仓库:https://atomgit.com/OpenHarmonyPCDeveloper/build_in_harmonyos
  • 上游源(软件出处):https://github.com/zeek/zeek (官方下载 https://download.zeek.org/zeek-8.2.1.tar.gz ,国内访问实测 200)
  • 鸿蒙 PC 社区:https://harmonypc.csdn.net/ ;项目申请:https://atomgit.com/OpenHarmonyPCDeveloper
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐