- 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 输入在四端输出字节相同(跨端一致性首次全语言验证)
57 lines
2.3 KiB
Rust
57 lines
2.3 KiB
Rust
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++");
|
||
}
|