Skip to content

feat(cpp): Bring in cleed++ library and ensure C/C++ interop (as in develop) #48

@Liam-Deacon

Description

@Liam-Deacon

Summary

Bring the cleed++ C++ library (currently present on the develop branch) into master, and ensure robust C/C++ interoperability so that C++ code (and future bindings) can safely consume the existing C implementation.

Background / current state

  • master builds several C libraries (leed, search, rfac, etc.) but does not build the src/cleed++ library.
  • The develop branch contains src/cleed++/ and a CMake option gate:
    • OPTION(BUILD_CPP_BINDINGS ... OFF) (origin/develop:CMakeLists.txt)
    • ADD_SUBDIRECTORY(cleed++) when enabled (origin/develop:src/CMakeLists.txt)
    • ADD_LIBRARY(cleedplusplus ...) with output name cleed++ (origin/develop:src/cleed++/CMakeLists.txt)
  • The develop branch also demonstrates extensive interop/bindings patterns for the C code via Cython wrappers and a Python packaging script (origin/develop:setup.py).

Motivation

  • Provide a higher-level, type-safe C++ API for modelling workflows.
  • Enable future packaging/bindings work (Python, WASM, etc.) by having a clear ABI boundary.
  • Reduce direct coupling to internal C structs and ad-hoc header inclusion.

Proposed scope

1) Port src/cleed++ to master

  • Import the src/cleed++/** sources and integrate them with the current CMake layout.
  • Add BUILD_CPP_BINDINGS (default OFF) to control whether the C++ library is built.
  • Ensure install rules are consistent with the rest of the project (library into lib/, headers into an appropriate include prefix).

2) Define and enforce C/C++ interoperability rules

Minimum requirements:

  • All public C headers must be C++-safe (wrap declarations with extern "C" guards when included from C++).
  • Avoid exposing internal C-only implementation headers directly to C++ consumers where possible.
  • Establish a stable C ABI boundary for C++ and bindings to target.

3) Add/standardise a C API facade (recommended)

  • Create a small “public C API” layer (names + headers) that:
    • wraps critical workflows (load inputs, run core steps, access key outputs)
    • hides internal structs behind opaque handles
    • returns explicit error codes/messages
  • cleed++ should prefer calling this C API facade rather than reaching deep into internal headers.

4) Validation / examples

  • Add a minimal C++ example program (or test) that links against the C libraries and the new cleed++ library.
  • Ensure it builds in CI (at least Linux/macOS) when BUILD_CPP_BINDINGS=ON.

Acceptance criteria

  • cmake -DBUILD_CPP_BINDINGS=ON ... builds and installs a cleed++ library (and headers) on all supported platforms.
  • Public C headers can be included from both C and C++ without warnings/errors.
  • A small integration test/example demonstrates C++ calling into the C implementation via the defined interop boundary.
  • Documentation explains:
    • how to enable/build the C++ library
    • what the supported ABI/API surface is (and stability guarantees)

Notes / risks

  • If the cleed++ API is not yet stable, explicitly version or namespace it and document stability expectations.
  • Prefer incremental adoption: start with a narrow slice of functionality (e.g., R-factor parsing + basic run orchestration) and expand.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions