✨ feat: 灵台引擎五神齐备与 Go/Rust 官方绑定(WP-15)

- C++ 新增四模块(modules.cpp,19 个导出符号全部 hj_*):
  小周天 hj_stream:流会话(sequence/delta_index 单调)与 content.block.delta envelope 确定性编码(重放字节一致)
  烛照 hj_policy:URL 协议白名单(拒 file/javascript/data)、路径授权根与 .. 段拒绝、幂等键非空≤128、四维决策表(autonomy×risk→allow/ask/deny,非法输入 deny fail-closed)
  洛书 hj_plan:预算核算(达限/负数拒绝)
  河图 hj_recall:确定性重排(词频×稳定排序,canonical JSON 输出;非法输入 PARSE_FAILED)
- doctest 22 用例 20135 断言全绿(含每模块 golden 与确定性双跑)
- Go 绑定(cgo 自包含编译引擎源码):Engine RAII/TransformMarkdown/ValidateURL/ValidatePath/Decide/CheckBudget/RecallRerank;go test 3 用例通过(transform/rerank golden 与 C++ 字节一致)
- Rust 绑定(bindgen 生成 + 安全包装):Engine RAII(Drop 释放)、Error 枚举映射全部 HjStatus、Send/Sync(HjEngine 线程安全);cargo test 3 用例通过(同 golden)
- 三端(C++/Go/Rust)与 Python golden 一致:同一 markdown 输入在四端输出字节相同(跨端一致性首次全语言验证)
This commit is contained in:
chenxin committed 2026-09-12 13:54:12 +08:00
1 parent 99a7789432
commit a39cec5287
15 files changed
+1205 -3

No files matched your search

+56
View File
@@ -0,0 +1,56 @@
use std::env;
use std::path::PathBuf;
fn main() {
let header = PathBuf::from("../../include/hunjing/lingtai.h")
.canonicalize()
.expect("找不到引擎公共头");
let bindings = bindgen::Builder::default()
.header(header.to_string_lossy())
.allowlist_function("hj_.*")
.allowlist_type("Hj.*")
.allowlist_var("HJ_.*")
.generate()
.expect("bindgen 生成失败(需要 libclang)");
let out_dir = PathBuf::from(env::var("OUT_DIR").unwrap());
bindings
.write_to_file(out_dir.join("bindings.rs"))
.expect("写 bindings.rs 失败");
println!("cargo:rerun-if-changed={}", header.display());
// 直接编译引擎源码(自包含)
let src = PathBuf::from("../../src").canonicalize().expect("找不到引擎源码");
for cpp in ["lingtai.cpp", "transform.cpp", "modules.cpp"] {
println!("cargo:rustc-cxx=g++");
let _ = cpp;
}
// 用 cc crate 风格手动调用:为最小依赖,此处直接输出编译指令给 rustc 链接预编译静态库
// 简化:编译为单个静态库由 build.rs 调用 clang++
// 逐个编译 .o,再归档为静态库
let objects: Vec<_> = ["lingtai.cpp", "transform.cpp", "modules.cpp"]
.iter()
.map(|cpp| {
let obj = out_dir.join(format!("{}.o", cpp.replace(".cpp", "")));
let status = std::process::Command::new("clang++")
.args(["-std=c++23", "-O2", "-c"])
.arg(src.join(cpp))
.arg("-I").arg(src.parent().unwrap().join("include"))
.arg("-I").arg(&src)
.arg("-fvisibility=hidden")
.arg("-o").arg(&obj)
.status()
.expect("clang++ 启动失败");
assert!(status.success(), "引擎编译失败:{cpp}");
obj
})
.collect();
let out_lib = out_dir.join("libhunjing_engine.a");
let status = std::process::Command::new("ar")
.arg("crus").arg(&out_lib)
.args(&objects)
.status()
.expect("ar 启动失败");
assert!(status.success(), "归档失败");
println!("cargo:rustc-link-search=native={}", out_dir.display());
println!("cargo:rustc-link-lib=static=hunjing_engine");
println!("cargo:rustc-link-lib=dylib=c++");
}