Safe Rust bindings for Ceres Solver, a C++ library for solving large-scale non-linear least squares (NLLS) optimization problems. The project is a Cargo workspace with three crates:
ceres-solver: Safe Rust bindings (main crate,src/)ceres-solver-sys: Unsafe FFI bindings via thecxxcrate (ceres-solver-sys/)ceres-solver-src: Builds and statically links bundled Ceres Solver from source (ceres-solver-src/)
MSRV: 1.85.0 (Rust 2024 edition)
# Build with bundled Ceres (preferred for development)
cargo build --features source
# Build with system-installed Ceres
cargo build
# Check all targets
cargo check --all-targets --workspace --features source
# Test with bundled source
cargo test --features source
# Test with system Ceres
cargo test --features system
# Format code
cargo fmt --all
# Lint (no warnings allowed)
cargo clippy --all-targets --workspace --no-default-features --features source -- -Dwarnings
# Run all pre-commit checks
pre-commit run --all-filessrc/ # Main crate (safe Rust API)
│ lib.rs # Library entry point with top-level examples
│ nlls_problem.rs # Core: NllsProblem builder
│ curve_fit.rs # 1-D curve fitting convenience wrapper
│ solver.rs # SolverOptions / SolverSummary
│ cost.rs # CostFunction type definitions
│ loss.rs # Loss functions (Huber, Cauchy, Tukey, …)
│ parameter_block.rs # ParameterBlock with bounds management
│ residual_block.rs # ResidualBlock ID types
│ error.rs # Error types (thiserror)
│ types.rs # Shared helper types
ceres-solver-sys/src/
│ lib.rs # Rust FFI declarations (cxx)
│ lib.cpp # C++ bridge implementation
│ lib.h # C++ header
ceres-solver-src/ # CMake-based static library builder
.github/workflows/test.yml # CI (Ubuntu + macOS, MSRV + stable)
- Standard Rust naming:
snake_casefor functions/variables,PascalCasefor types - Builder pattern throughout (e.g.,
ResidualBlockBuilder,SolverOptionsBuilder) - Consuming methods — builders take
selfand return a new/modified type - Error types use
thiserror; all error enums live insrc/error.rs - Doc comments:
//!for module-level,///for items; include examples where useful - Minimize new dependencies; for MSRV compatibility, versions of
cxx/cxx-buildmay be pinned
- Check the feature exists in the supported Ceres Solver C++ API (2.2)
- If adding FFI:
- Update
ceres-solver-sys/src/lib.handlib.cpp(C++ bridge) - Update
ceres-solver-sys/src/lib.rs(Rustcxxdeclarations)
- Update
- Add safe Rust wrappers in the appropriate
src/file - Write tests (unit tests in the same file; integration tests under
tests/) - Use the
approxcrate for floating-point comparisons in tests - Update the feature status checklist in
README.mdif applicable - Add an entry to
CHANGELOG.md(Keep a Changelog format, semantic versioning)
GitHub Actions runs on Ubuntu and macOS against MSRV (1.85) and stable Rust:
cargo-fmt— formatting checkcargo-clippy— lint check (-Dwarnings)ceres-built-from-source— tests with--features sourcesystem-ceres— tests with system-installed Ceres
Windows support is limited/experimental and not part of CI.
- All unsafe FFI code is isolated in
ceres-solver-sys;ceres-solvermust remain safe - Parameter blocks use pin semantics to ensure stable memory addresses across the FFI boundary
- Use modern C++17 features through
cxx; avoid raw pointer arithmetic in new code