docs/current/02-构建与上手/构建指南.md
GitHub ↗
当前有效

Vitro 构建指南

1686 字·约 5 分钟 阅读 2026-10-10 17:07

最后核对:2026-10-07(构建节补统一入口 launcher 免构建快径 + Node 版本要求细化 ≥25——复核补漏批抓漏〔#49 批一 2026-10-06 落地晚于本册 10-05 重写〕。前一沿革 2026-10-05 S9 工序④删区整篇重写为单轨版——原 Rust 冻结对照 oracle 构建内容〔cargo 三出口 / clippy / wasm32 / lint_check / shadow ×2 / 三层一致性 / 工程健康看板 / 内存安全预检 / DLL FAQ〕随 native/ 物理删除整体失效,全部移除;Rust 构建历史见 tag rust-oracle-freeze 与 git 历史。前一沿革 2026-09-29)

单轨口径(2026-10-05 起):仓库唯一实现 = MoonBit(moonbit/)。其构建 / 闸门 / 发布流程以 moonbit/AGENTS.md 为权威,本指南不重复——本指南只讲 宿主环境要求、Go 防线驱动跑法与常见问题。

历史前端构建(Flutter / Android / iOS / web 部署)已随 2026-09-11 前端切割迁出本仓库, 对应脚本见标签 before-frontend-split。


环境要求

组件 版本 用途
Go 1.27+(见根 go.mod) 全部测试防线驱动与工具脚本(go run ./scripts/<name>;零第三方依赖,离线可跑)
MoonBit 工具链(moon / moonc) 版本以 scripts/toolchain_baseline.txt 锁定 引擎构建 / 测试 / 差分对拍(moon test 已是 CI 门禁)
Clang / Clang++ 任意近期版本 Clang 直拍门禁的 Golden 生成(CI 硬门禁,缺失即 fail fast);Windows 上 MoonBit native 目标构建须 MOON_CC=clang(moon#2254 构建悬崖,见 AGENTS.md 纪律 11)
Node.js ≥25(统一入口 launcher wasm 臂要求;不足自动降级 native exe)/ 任意近期版本(冒烟宿主) launcher wasm 臂(scripts/bin/vitro)、wasm-gc 网关冒烟(scripts/wasm_gateway/host.js)、demo 冒烟(scripts/demo_smoke/)

快速检查:

clang --version                 # 需要能直接调用(直拍 Golden 唯一来源)
go version                      # 见根 go.mod
moon version                    # MoonBit 工具链(version 工具链探针锁定基线)
node --version                  # 冒烟宿主

构建

日常临时验证 / 快速跑 C 程序免构建:统一入口 launcher scripts/bin/vitro(sh)/ vitro.cmd(cmd)——默认 wasm 臂直接消费 gateway/wasm/wasm.wasm(与 demo 同产物,需先 moon build --release --target wasm-gc gateway/wasm 一次),node 缺失/过旧自动降级 native exe;双臂同形由 CI 闸 vitro_cli_smoke 锁定。参数面见 CLI使用手册.md。下述源码构建用于闸门验证与产物重建。

MoonBit 引擎(唯一实现)

cd moonbit && moon check && moon test      # 静态检查 + 全量测试
MOON_CC=clang moon build --release --target native cmd/vitro   # CLI 总入口(run/compile/step/api)
MOON_CC=clang moon build --release --target native cmd/serve   # JSON-lines 出口
MOON_CC=clang moon build --release --target wasm-gc gateway/wasm   # wasm-gc 单出口制品

Windows 提示:moon build --target native 默认走 MSVC cl 链接后端,本仓实测病态慢 (moon#2254);一律设 MOON_CC=clang。构建/发布全流程见 moonbit/AGENTS.md。

原 Rust 实现的三出口构建(cdylib / vitro_cli / wasm32)已随 2026-10-05 删区退役—— 完整终态见 tag rust-oracle-freeze;现行出口面 = wasm-gc 制品 + cmd/serve / cmd/vitro。


测试与静态检查

MoonBit 侧:

cd moonbit && moon check && moon test && moon fmt

Go 防线驱动(脚本全表与拦截对象见脚本总清单与必跑防线.md):

go vet ./scripts/...
go test ./scripts/...

测试防线(最常用五条入口)

  1. Clang 直拍(层 2,CI 硬门禁)——引擎 vs Clang 本尊,全量语料逐例对照:

    go run ./scripts/clang_direct --check-known
    go run ./scripts/clang_direct

    机制与白名单见 Clang直拍门禁.md。

  2. 运行期对拍(层 1)——引擎 vs 冻结 golden(工序③固化锚)三联 diff:

    cd moonbit && MOON_CC=clang moon build --release --target native cmd/run && cd ..
    go run ./scripts/vm_diff
  3. serve 协议冒烟:go run ./scripts/serve_smoke

  4. 回放断言:go run ./scripts/replay

  5. 文档事实对账:go run ./scripts/facts --strict check

产物新鲜度门禁(直拍/回放均生效):防线读的都是 release 产物(moonbit/_build 下的 cmd/run / cmd/serve exe),若产物没跟着源码重建,断言会在"验证陈旧二进制"的情况下 全绿——这比失败更坏。驱动内置新鲜度检查(mtime 触发 + 构建复核); 结论:改完引擎先重建再跑防线。

提速设施:Clang Golden 缓存(.clang_cache_cd/,key = 源码 + stdin + clang 版本 + 参数)

  • 并行执行;缓存与 worker 目录已 gitignore——改动用例后无需手动清缓存(源码哈希变化自动失效)。

标准输入:用例可自带同名 .in 文件,Clang 与 Vitro 喂同一份字节(缓存 key 纳入真实 stdin)。

⚠️ 并行化对顺序敏感:用例加载与分片分发必须确定性(排序 + 按用例序重排), 否则会出现"结果错配但门禁仍绿"的静默失败。


脚本清单

scripts/ 全量脚本(CI 门禁驱动 / 差分对拍 / 生成器)与 本地提交前必跑矩阵已独立成册,见:

脚本总清单与必跑防线.md(脚本入册的单一来源; 各脚本用法以自身 .go 头注为权威)。

MoonBit 侧验证命令另见 moonbit/AGENTS.md "构建与验证命令"一节。


常见问题

Q1: 防线报 "clang not found"

直拍防线以 Clang 为唯一 Golden 来源,缺失时故意 fail fast(exit 2)而不是静默跳过。 安装 LLVM/Clang 并确保 clang(C++ 语料还需 clang++)在 PATH 中。

Q2: moon build --target native 极慢(Windows)

MSVC cl 链接后端的构建悬崖(moon#2254)。 一律 MOON_CC=clang 后再构建(全量约 17s 实测)。

Q3: 改了测试用例但直拍结果没变

缓存按源码哈希自动失效,正常无需干预;若怀疑缓存异常,用 --refresh-clang 强制全量重算 (CI 夜间 schedule 同款)。

Q4: Rust 版怎么构建 / 跑?

Rust 实现已于 2026-10-05 删区退役,仓库内无 Rust 代码可构建。历史终态与构建方法见 tag rust-oracle-freeze(档案);现行差异台账 = scripts/diff_ledger/ledger.json。

Q5: 前端(Flutter / Android / iOS / Web)怎么构建?

前端已于 2026-09-11 整体迁出本仓库,本仓库只做后端。 切割前最后完整状态见标签 before-frontend-split:

git checkout before-frontend-split -- CideFlutter