feat(engine): rename facade to oakengine, build liboakengine.dylib

- src/facade/rust -> src/engine/rust; package oakfacade -> oakengine
- crate-type += cdylib; module crates are real deps; linkage anchors
  force-link module C ABIs into the dylib
- build.rs: -undefined dynamic_lookup for host-provided oakcore_*/fb_*
- nm: 749 oakengine_* + 687 module oak*_* exports; undefined set is
  only the intended host-provided symbols
- worker/cli updated to the new path/name; undo test race fix
This commit is contained in:
2026-08-10 16:55:35 +08:00
parent e563b340ac
commit 0ca9cad448
66 changed files with 3398 additions and 204 deletions
+1666 -3
View File
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -37,7 +37,7 @@ clap = { version = "4", features = ["derive"] }
# deferral (src/deferred.rs). The extern declarations in src/ffi.rs mirror
# the engine headers verbatim and resolve against this rlib the moment a
# family is wrapped -- no manifest change needed.
oakfacade = { path = "../../src/facade/rust" }
oakengine = { path = "../../src/engine/rust" }
[profile.release]
panic = "unwind"
+6 -6
View File
@@ -17,7 +17,7 @@
//! Facade-family availability, mirroring `src/facade/rust/src/deferred.rs`.
//!
//! Every `oak-cli` subcommand depends on one or more families of the
//! `oakengine_*` C ABI. Those families live in the `oakfacade` crate, and
//! `oakengine_*` C ABI. Those families live in the `oakengine` crate, and
//! some of them are **deferred**: the facade does not wrap them yet, so the
//! subcommands must report a clear "not yet available" error instead of
//! calling into the facade (the calls would not link, and faking behavior
@@ -47,7 +47,7 @@ pub struct DeferredFamily {
pub const INIT: DeferredFamily = DeferredFamily {
name: "init",
headers: "init.h",
reason: "the facade shell (oakengine_init/shutdown) is not wrapped in oakfacade yet (its scope table covers only undo/common/audio/plugin)",
reason: "the facade shell (oakengine_init/shutdown) is not wrapped in oakengine yet (its scope table covers only undo/common/audio/plugin)",
};
/// `project.h` + `footage.h` — the oaknode module family.
@@ -80,13 +80,13 @@ pub const TIMELINE: DeferredFamily = DeferredFamily {
pub const RENDER: DeferredFamily = DeferredFamily {
name: "render",
headers: "renderer.h",
reason: "deferred for session scope: the engine renderer.h family is not wrapped in oakfacade yet (no structural blocker)",
reason: "deferred for session scope: the engine renderer.h family is not wrapped in oakengine yet (no structural blocker)",
};
/// `exporter.h` — export/encode family.
///
/// Facade deferred.rs: exporter is a "genuinely facade-only area" (the
/// liboakengine assembly layer) with no files in the oakfacade crate.
/// liboakengine assembly layer) with no files in the oakengine crate.
pub const EXPORT: DeferredFamily = DeferredFamily {
name: "exporter",
headers: "exporter.h",
@@ -107,7 +107,7 @@ pub fn require(families: &[&DeferredFamily]) -> Result<(), String> {
detail.push_str(&format!("\n - {} ({}): {}", f.name, f.headers, f.reason));
}
Err(format!(
"not yet available in the Rust facade (oakfacade): these family(ies) are still deferred \
"not yet available in the Rust facade (oakengine): these family(ies) are still deferred \
(see src/facade/rust/src/deferred.rs):{detail}"
))
}
@@ -126,7 +126,7 @@ mod tests {
let err = require(&[&INIT]).unwrap_err();
assert!(err.contains("not yet available"));
assert!(err.contains("init"));
assert!(err.contains("oakfacade"));
assert!(err.contains("oakengine"));
}
#[test]
+3 -3
View File
@@ -28,15 +28,15 @@
//! - `engine/include/oakengine/exporter.h` (export options + render)
//!
//! All of these families are **deferred** in the Rust facade crate
//! (`oakfacade`, `src/facade/rust/src/deferred.rs`), so none of the symbols
//! (`oakengine`, `src/facade/rust/src/deferred.rs`), so none of the symbols
//! below is referenced from this crate yet — the subcommands gate on
//! [`crate::deferred`] and report "not yet available" instead of calling
//! them. The declarations exist so that:
//!
//! 1. the exact contract the CLI expects is pinned in one place (types,
//! signatures, string conventions, error codes), and
//! 2. when a family is wrapped by oakfacade, the call-through code in
//! `src/cmd/` resolves against the already-linked `oakfacade` rlib
//! 2. when a family is wrapped by oakengine, the call-through code in
//! `src/cmd/` resolves against the already-linked `oakengine` rlib
//! without any manifest or signature churn.
//!
//! Nothing here is ever called today, so no symbol needs to exist in the
+1 -1
View File
@@ -30,7 +30,7 @@
//! 64 usage error.
//!
//! The facade families every subcommand depends on (init/project/timeline/
//! render/footage/exporter) are still **deferred** in the `oakfacade` crate
//! render/footage/exporter) are still **deferred** in the `oakengine` crate
//! (see `src/facade/rust/src/deferred.rs`), so each subcommand validates its
//! arguments faithfully, then reports the deferral with its reason and exits
//! with the C++-compatible code — never crashing, never faking output.
+3 -1
View File
@@ -71,7 +71,9 @@ fn info_on_a_fixture_reports_not_yet_available() {
let (code, _stdout, stderr) = run(&["info", "tests/project_with_footage.ove"]);
assert_eq!(code, 1);
assert!(stderr.contains("error: info: not yet available"), "stderr: {stderr}");
assert!(stderr.contains("oakfacade"));
// The crate was renamed oakfacade -> oakengine; the deferral reason
// names the current crate.
assert!(stderr.contains("oakengine"));
}
#[test]