feat(kpm): remove C++ FFI as default — pure Rust FreakMatcher complete (#142)#175
Merged
Merged
Conversation
#142) Closes M9-3. The structural M9-3 work (Cargo.toml default feature set, build.rs gating of C++ compilation, conditional cpp_backend module) was done incrementally during M9-1 and M9-2; this commit makes the pure-Rust default explicit, CI-gated, and documented. ## What this commit lands 1. **Explicit `default = []`** in `crates/core/Cargo.toml`. The default feature set was already implicitly empty (no `default` line existed), but stating it explicitly makes the M9-3 intent self-documenting alongside the `ffi-backend = []` line that already existed. 2. **`required-features = ["log-helpers", "ffi-backend"]`** on the `nft_marker_gen` example. It uses `CppFreakMatcher` directly to build `.fset3` files, so it must explicitly opt in to the C++ backend now that the default doesn't pull it in. (Other `CppFreakMatcher` consumers — `simple_nft_dual` — were already opt-in via `dual-mode`.) 3. **New `pure-rust-build` CI job** in `.github/workflows/ci.yml`. Ubuntu-only (the invariant is build-system gating, not platform-specific compilation). Crucially does NOT install `libclang-dev` — if any unconditional bindgen/cc dependency ever leaks into the no-features build path, this job fails. Runs `cargo fmt --check`, `cargo check`, `cargo clippy -D warnings`, `cargo build`, and `cargo test` on `webarkitlib-rs` with **no** `--features` flag. Catches the strongest possible regression class for this milestone. 4. **ARCHITECTURE.md updates**: feature-flag table now lists `(default)` as the first row (pure Rust); `kpm::rust_backend` and `kpm::cpp_backend` are documented with their default/opt-in roles; the "Building and Testing" section restructures around "Pure Rust tracking (default — no C++ compiler needed)" and "Opt-in: C++ FFI backend" subsections. 5. **README.md updates**: new "Pure Rust tracking" and "Building without C++" sections explicitly state that `cargo add webarkitlib-rs` works on hosts without a C++ toolchain; the `ffi-backend` feature table entry now describes it as opt-in for validation + legacy `.fset3` generation. 6. **BENCHMARKS.md update**: new "KPM / NFT performance (M9-3 status)" section documents that the existing `marker_bench` measures `ar_detect_marker` (barcode/template marker detection), not the FreakMatcher path — so it can't satisfy the "within 20% of C++ on pinball-demo" perf target on its own. The functional parity evidence (test_dual_mode_no_divergence_on_pinball, #169 absolute_corner_error, #173 cross_stack_parity, #155 kpm_regression test_full_pipeline_pose) all pass within their tolerances; the within-20% wall-clock measurement is explicitly deferred to a follow-up Criterion bench (`kpm_bench.rs`), permitted by #142's escape hatch: "If slower, open a follow-up performance issue rather than blocking this PR." ## Verification - `cargo fmt --all -- --check` clean - `cargo check -p webarkitlib-rs` clean (no features, no C++) - `cargo clippy -p webarkitlib-rs -- -D warnings` exit 0 - `cargo build -p webarkitlib-rs` clean (no features) - `cargo test -p webarkitlib-rs` — 431 passed, 7 ignored (no features) - `cargo build -p webarkitlib-rs --features ffi-backend` clean - `cargo test -p webarkitlib-rs --features ffi-backend --lib kpm` — 241 passed (FFI path unchanged) ## Follow-ups - **#174**: upgrade criterion 0.5.1 → 0.8.x (surfaced during this PR; intentionally separated per CLAUDE.md "one issue per branch"). - KPM-specific Criterion benchmark to satisfy the within-20% target with real wall-clock numbers (referenced in BENCHMARKS.md). Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
19 tasks
kalwalt
added a commit
that referenced
this pull request
Jun 5, 2026
Closes #139 (M9 milestone umbrella). Makes the pure-Rust FreakMatcher / VisualDatabase the default backend. A plain `cargo build` now produces a working NFT tracker with no C++ toolchain (clang / libclang / cc) required — the C++ FFI is opt-in behind `--features ffi-backend`, used only for cross-validation, regression baselines, and the `nft_marker_gen` example. Sub-milestones folded in (16 sub-PRs): M9-1 / #140 — VisualDatabase port .............. #145, #149, #151, #153 M9-2 / #141 — RustFreakMatcher + DualFreakMatcher #156, #159 M9-3 / #142 — pure-Rust as default ............. #175 Cross-cutting work that came out of M9: - Cross-platform / cross-stack matcher determinism: Rust HashMap → BTreeMap (#170 → #171) C++ unordered_map → std::map (WebARKitLib#39, absorbed via #172) - Hand-annotated absolute corner-error gate (#166 Track A): #163 dump_pyramid, #165 fixtures, #167 annotator tool, #168 annotations, #169 the gate itself. Finding: Rust 5.27 px vs C++ 18.79 px max corner error on pinball-demo — pure-Rust backend is more accurate. - Cross-stack parity vs jsartoolkitNFT-Node 1.10.0 (#173, jsartoolkitNFT#584 Track 2): sidecar bridge package + Linux CI gate (rot ≤ 0.08, trans ≤ 10 mm). - Restored kpm_regression Linux baseline (#155 → #158). CI surface added: - pure-rust-build job (ubuntu, non-recursive checkout, no libclang-dev) — guards the M9-3 invariant that the default build path never leaks a C++ dependency. - ffi-backend integration tests + absolute_corner_error + cross_stack_parity on Linux in kpm-build. Stats: 31 commits, 45 files, +9,051 / −133. Deferred (not blocking M9): #142's "within 20% of C++ on pinball-demo" wall-clock target — `marker_bench` measures barcode detection, not KPM. A dedicated `kpm_bench.rs` is filed as a follow-up. Other follow-ups: #161 (WASM browser examples), #174 (criterion 0.5 → 0.8), #177 (raise M9 patch coverage 84.76% → ≥90%). Closes: #139, #140, #141, #142, #155, #157, #160, #166, #170
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #142 (M9-3). Last piece of the M9 milestone.
TL;DR
The structural M9-3 work (Cargo.toml default features, build.rs gating, conditional
cpp_backendmodule) was done incrementally during M9-1 / M9-2. This PR makes the pure-Rust default explicit, CI-gated, and documented.After merging, a plain
cargo add webarkitlib-rs && cargo buildworks on machines without a C++ compiler. Theffi-backendfeature stays available as an opt-in for validation + legacy.fset3marker generation.Diff scope
5 files changed, +146 / -9 lines. No source/test changes — all infrastructure + docs.
crates/core/Cargo.tomldefault = [];nft_marker_genexample now requiresffi-backend(it usesCppFreakMatcherdirectly).github/workflows/ci.ymlpure-rust-buildjob (ubuntu-only, nolibclang-devinstall) — provescargo build/testsucceed without a C++ toolchainARCHITECTURE.md(default)as first row;kpm::rust_backend/kpm::cpp_backenddocumented with default/opt-in roles; "Building and Testing" restructuredREADME.mdffi-backendclarified as opt-in for validation + legacy.fset3generationcrates/core/benches/BENCHMARKS.mdmarker_benchcan't satisfy the within-20% target on its own, with functional-parity evidence + deferred-perf-bench noteVerification (run locally)
cargo fmt --all -- --checkcleancargo check -p webarkitlib-rs(no features) cleancargo clippy -p webarkitlib-rs -- -D warningsexit 0cargo build -p webarkitlib-rs(no features) cleancargo test -p webarkitlib-rs(no features) → 431 passed, 7 ignoredcargo build -p webarkitlib-rs --features ffi-backendcleancargo test -p webarkitlib-rs --features ffi-backend --lib kpm→ 241 passed (FFI path unchanged)Acceptance criterion from #142
pure-rust-buildCI job enforces it going forwardkpm-buildmatrix continues to exercise itcargo publish --dry-runsucceedsmarker_benchmeasures barcode marker detection, not KPM/FreakMatcher — see BENCHMARKS.md for the functional-parity evidence + follow-up planFollow-ups (filed)
What this closes for M9 as a whole
With #142 (this PR) merged, the M9 milestone is complete:
Plus the cross-cutting work that came out of M9 testing:
🤖 Generated with Claude Code