# feat(api,cli): generate CMakeLists.txt for standalone C/C++ nodes and support cmake find_package#1763
# feat(api,cli): generate CMakeLists.txt for standalone C/C++ nodes and support cmake find_package#1763Ts-sound wants to merge 26 commits into
find_package#1763Conversation
- Add build.rs to generate CMake config files on cargo build - Create cmake templates for Config and ConfigVersion files - Version automatically derived from CARGO_PKG_VERSION - Library symlinked to lib/ for standard CMake layout - Users can use: find_package(dora-node-api-c REQUIRED)
- Add CMakeLists-template.txt for standalone C nodes - `dora new --kind node --lang c` now generates CMakeLists.txt - Uses find_package(dora-node-api-c REQUIRED) pattern - Remove unused dora-node-api-c/dora-operator-api-c deps from cli - Resolve TODO: Makefile? comment
…-c::extra - Add dora-node-api-c::extra interface library for platform deps - Linux: pthread dl m rt - macOS: CoreServices Security frameworks + pthread m c resolv - Windows: system libs (advapi32, kernel32, ws2_32, etc.) - CLI template now links extra target instead of explicit m
- Add platform/arch detection at cmake config load time - Embed built target info from build.rs (@target@ placeholder) - Use STREQUAL for exact string matching (not MATCHES regex) - Add target mismatch FATAL_ERROR for cross-platform safety - Fix symlink creation: use `let _ = remove_file` to ignore errors - Print built target info during cargo build
- Add cmake config directory to package structure
- Copy dora-node-api-c cmake files (generated by build.rs)
- Unix: cp -r target/{target}/release/lib/cmake/dora-node-api-c
- Windows: Copy-Item -Recurse cmake/dora-node-api-c
- Package structure now supports find_package(dora-node-api-c)
- Check TARGET env var when building with `--target` flag
- cmake files now generated at correct path:
- Without --target: target/{profile}/lib/cmake/dora-node-api-c/
- With --target: target/{target}/{profile}/lib/cmake/dora-node-api-c/
- Fixes CI workflow `cp` error when packaging published libraries
- cmake already shows target info via message(STATUS) during configuration - cargo build output is now clean without warnings
- OUT_DIR is managed by cargo, respects --target-dir and config - Works correctly with or without explicit --target flag - Fixes dangling symlink issue in default builds - Eliminates 3-parent guess from CARGO_MANIFEST_DIR
- Handle arch name mismatch: AMD64 vs x86_64, arm64 vs aarch64 - Normalize at cmake side: AMD64/amd64/x86_64 -> x86_64 - Normalize at cmake side: ARM64/arm64/aarch64 -> aarch64 - Fixes target matching on Windows/macOS where names differ from Cargo
- Test dora new --lang c → cmake → build on Linux/Windows/macOS - Trigger on changes to apis/c/node or cli c template - Verify complete find_package workflow end-to-end
|
Merging to
After your PR is submitted to the merge queue, this comment will be automatically updated with its status. If the PR fails, failure details will also be posted here |
- Remove '-node' suffix from CMake executable target name - Update cmake-smoke.yml to verify correct build output path - Executable now named 'test-node' instead of 'test-node-node'
|
@phil-opp Could you please review the changes (about |
|
Claude found the following issue: 🔴 Windows: the static lib never makes it into
|
|
OK, I will add this task as a follow-up to |
- build.rs now only generates cmake config and header to OUT_DIR - Add scripts/c-cpp-libraries/stage-c-node.sh for Unix staging - Add scripts/c-cpp-libraries/stage-c-node.ps1 for Windows staging - Update publish workflow to use staging scripts - Rename cmake-smoke.yml to test-c-cpp-libraries.yml - Staging happens in CI, not in build.rs (cargo contract compliant)
|
We also have an existing |
- Scripts now receive TARGET_DIR (target/release) not BUILD_DIR + find OUT_DIR - build.rs writes directly to TARGET_DIR/lib/cmake/ and TARGET_DIR/include/ - Remove unreliable find + grep OUT_DIR discovery - Parameter renamed: BuildDir -> TargetDir for clarity
|
This file is used to simultaneously compile |
- Use broader paths: apis/**, binaries/**, scripts/**, .github/workflows/** - Remove invalid 'apis/c++/**' path pattern (++ causes parse error) - Fix parameter name: BuildDir -> TargetDir in publish workflow - Consistent with staging script changes
|
This file can be simplified. project(cxx-dataflow LANGUAGES CXX)
set(CMAKE_CXX_STANDARD 20)
set(CMAKE_CXX_FLAGS "-fPIC")
find_package(dora-node-api-c REQUIRED)
## listener_1
add_executable(listener_1 listener_1/node.cc)
target_link_libraries(listener_1 PRIVATE dora-node-api-c::dora-node-api-c dora-node-api-c::extra)
## talker_1,talker_2
...
|
- Use CARGO_BUILD_TARGET to detect if --target flag was used - Output structure: - Without --target: target/<profile>/lib/cmake/, include/ - With --target: target/<target>/<profile>/lib/cmake/, include/ - Staging script now works correctly with TARGET_DIR parameter - Removed dependency on OUT_DIR for final output location
|
@phil-opp |
- build.rs now writes cmake config and headers to target/<profile>/dora-node-api-c/ alongside the static library, enabling predictable artifact paths without search - add xtask crate with stage-c-node command for cross-platform staging - update CI workflows to use cargo run -p xtask instead of shell scripts - delete scripts/c-cpp-libraries/stage-c-node.sh and .ps1 - add scripts/c_cpp_lib/test-stage.sh to verify debug, release, and --target builds
…/C++ crates - Replace crate-specific cmake template with generic dora-api-config.cmake.in supporting @Package@, @target@, @LIB_UNIX@, @LIB_WIN@ placeholders - Add cmake config generation to dora-operator-api-c, dora-node-api-cxx, dora-operator-api-cxx build.rs (previously only dora-node-api-c) - C crates stage to TARGET_DIR/<crate>/ alongside .a; C++ crates stage to target/cxxbridge/<crate>/ (cmake + header only, no .cc) - Generalize xtask stage command to support all 4 crates via single subcommand - Update publish-c-cpp-libraries.yml: replace all manual cp with xtask stage - Update test-stage.sh to support --all flag and 4 crate parameters
…plate - Add CXX_BRIDGE_FILES variable to cmake config for C++ crates (populated with .cc path; empty for C crates) so users can add it to add_executable - Stage cxxbridge .cc source files via xtask stage command - Fix CMakeLists-template.txt for C++ (uses CXX_BRIDGE_FILES variable) - Fix C standard in C template (20 -> 11, CMake only supports 90/99/11/17/23) - Add CMakeLists.txt generation to cxx template module (parity with C) - Fix cxx node template to use correct cxxbridge API (next_event, event_type, event_as_input instead of next_input) - Add build-test.sh to verify C and C++ nodes build end-to-end with dora new + CMake (temp/ directory preserved for inspection)
…bdirectory - Replace ExternalProject_Add in dataflow cmake-template.txt with find_package(dora-node-api-c/cxx REQUIRED) + add_subdirectory for talker_1, talker_2, listener_1 - Simplify create_cmakefile() to only replace name placeholder (remove DORA_ROOT_DIR / workspace path logic) - Rename build-test.sh -> build_node_test.sh, test-stage.sh -> stage_test.sh - Add build_dataflow_test.sh to verify C/C++ dataflow builds end-to-end
- Update directory structure to show lib/cmake/ layout - Replace manual CMake examples with find_package(dora-node-api-c/cxx) - Add Using dora new section with node and dataflow workflows - Update Building from Source with xtask stage instructions - Retain Manual Linking as advanced reference
|
@phil-opp Could you please review the changes? |
|
Closing as superseded-in-part by #1851, with thanks to @Ts-sound for laying out the full design. Why closeThree weeks after this PR opened, #1851 (rescue of #1514) merged the CLI-template piece of #1756 using a different approach: What this PR's contribution split into✅ Already on main (via #1851 / pre-existing infra):
❌ Not on main, real value, surgical follow-up coming:
The residual scope (find_package infra + xtask + test CI, with Phil's Windows fix applied) will land as a focused follow-up PR — roughly 400-600 lines instead of 1561, with no conflict against #1851's templates. I'll credit you with Tracking
Thanks for the thorough design write-up — it made the triage straightforward. |
…-up of #1763) Adds CMake `find_package(dora-node-api-c)` / `find_package(dora-node-api-cxx)` support for consumers of the published static libraries, without disturbing #1851's `dora new --kind node --lang c/cxx` CLI templates (which serve the orthogonal source-tree-build workflow). Closes the residual piece of #1756 left over after #1763 was closed in favour of this narrower rescue. Co-authored-by @Ts-sound (tong), whose #1763 contributed the design and most of the code. What is added ============= * `apis/c/node/build.rs` (new), `apis/c/operator/build.rs`, `apis/c++/node/build.rs`, `apis/c++/operator/build.rs` — each build.rs now emits a `<crate>Config.cmake` + `<crate>ConfigVersion.cmake` at the standard `<prefix>/lib/cmake/<crate>/` layout, copies the public headers into `<prefix>/include/`, and for cxx crates also stages the generated `.cc` so consumers can compile it alongside their code. The config files import the static lib as a `<crate>::<crate>` target and an `<crate>::extra` interface target carrying the platform link dependencies (winapi libs / Apple frameworks / pthread+dl+m+rt) so downstream CMakeLists never have to list them by hand. Built-target vs current-target is checked at configure time, so an archive-extracted-on-wrong-architecture is caught before the link step. * `apis/c/node/cmake/dora-api-config.cmake.in`, `apis/c/node/cmake/dora-api-version.cmake.in` — the generic cmake templates shared by all four crates (placeholders: `@PACKAGE@`, `@TARGET@`, `@LIB_UNIX@`, `@LIB_WIN@`, `@CXX_BRIDGE_FILES@`, `@VERSION@`). * `xtask/` — new workspace crate, `cargo run -p xtask -- stage <crate> <target_dir> <prefix>`, assembles the staging output produced by build.rs into a find_package-ready prefix directory. Handles both C-style (single staging dir under target_dir) and cxx-style (cmake config in cxxbridge tree, static lib in target_dir, cxxbridge .h/.cc also copied) layouts. Walks ancestor directories of `target_dir` to locate the cxxbridge tree, since the cxx tool always emits to `target/<triple>/cxxbridge/` while the static lib may be either `target/<profile>/` or `target/<triple>/<profile>/` depending on whether `--target` was passed. * `.github/workflows/test-c-cpp-libraries.yml` — new test workflow. Builds each C/C++ API crate, stages it via xtask, then runs `cmake configure + cmake build` against a checked-in fixture (`tests/cmake-find-package-c/`, `tests/cmake-find-package-cxx/`). Runs on ubuntu-22.04, macos-latest, windows-latest. Path-scoped so it only runs when the C/C++ surface changes. * `tests/cmake-find-package-c/`, `tests/cmake-find-package-cxx/` — tiny fixtures that exercise the find_package contract: minimal CMakeLists.txt + main.{c,cc} that take the address of a symbol from the dora C/C++ API. If the cmake config files are missing or the staging layout drifts, these fail at cmake configure or link time. * `.github/workflows/publish-c-cpp-libraries.yml` — staging step rewritten to delegate to `xtask stage` instead of carrying parallel Unix shell / pwsh `cp` blocks. Addresses @phil-opp's review concern from #1763 — staging now happens strictly *after* `cargo build` finishes the static lib, never during build.rs (where the .lib does not yet exist on a fresh Windows build). * `apis/C-CPP-LIBRARIES.md` — adds a "Recommended: find_package" section showing the canonical consumer recipe. Demotes the existing hand-rolled include/link-path examples to a "Legacy" section. Adds a "build from source with xtask" recipe so a local build produces the same layout consumers see in the GitHub release artefacts. What is NOT added (deliberately out of scope) ============================================= * No changes to `binaries/cli/src/template/{c,cxx}/*-cmake-template.txt`. Those templates (added by #1851 / rescue of #1514) use `ExternalProject_Add` against a source-tree checkout, which serves developers cloning the repo. The find_package idiom here serves the orthogonal "downloaded a release tarball" workflow. The two coexist: a future PR may add a `dora new --cmake find-package` flag that emits a find_package-style CMakeLists, but that is a separate UX decision. * No new public Rust API. The reply enum stays compatible. No semver- affecting type changes. * No CLI surface changes. `dora new --kind node --lang c/cxx` still emits the same template. * Phil's `cmake-templates.txt` duplication concern from #1763: inspected and confirmed not duplicative — the CLI template scaffolds into user projects (per-project CMakeLists), while `dora-api-config.cmake.in` is the package config consumed by find_package. Different layers. Verification ============ cargo fmt --all -- --check cargo clippy --all --exclude dora-{node-api,operator-api,ros2-bridge}-python -- -D warnings cargo test -p xtask -p dora-node-api-c -p dora-operator-api-c \ -p dora-node-api-cxx -p dora-operator-api-cxx cargo check --examples End-to-end find_package round-trip exercised locally on macos-aarch64: cargo build --release -p dora-node-api-c cargo run -p xtask -- stage dora-node-api-c target/release dora-c-prefix cmake -S tests/cmake-find-package-c -B build-c \ -DCMAKE_PREFIX_PATH=$(pwd)/dora-c-prefix cmake --build build-c # built smoke executable; exit 0 cargo build --release -p dora-node-api-cxx --target aarch64-apple-darwin cargo run -p xtask -- stage dora-node-api-cxx \ target/aarch64-apple-darwin/release \ dora-cpp-prefix cmake -S tests/cmake-find-package-cxx -B build-cxx \ -DCMAKE_PREFIX_PATH=$(pwd)/dora-cpp-prefix cmake --build build-cxx # built smoke executable; exit 0 CI test workflow drives the same recipe on linux/macos/windows. Co-authored-by: Ts-sound <Ts-sound@users.noreply.github.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-up of #1763) Adds CMake `find_package(dora-node-api-c)` / `find_package(dora-node-api-cxx)` support for consumers of the published static libraries, without disturbing #1851's `dora new --kind node --lang c/cxx` CLI templates (which serve the orthogonal source-tree-build workflow). Closes the residual piece of #1756 left over after #1763 was closed in favour of this narrower rescue. Co-authored-by @Ts-sound (tong), whose #1763 contributed the design and most of the code. What is added ============= * `apis/c/node/build.rs` (new), `apis/c/operator/build.rs`, `apis/c++/node/build.rs`, `apis/c++/operator/build.rs` — each build.rs now emits a `<crate>Config.cmake` + `<crate>ConfigVersion.cmake` at the standard `<prefix>/lib/cmake/<crate>/` layout, copies the public headers into `<prefix>/include/`, and for cxx crates also stages the generated `.cc` so consumers can compile it alongside their code. The config files import the static lib as a `<crate>::<crate>` target and an `<crate>::extra` interface target carrying the platform link dependencies (winapi libs / Apple frameworks / pthread+dl+m+rt) so downstream CMakeLists never have to list them by hand. Built-target vs current-target is checked at configure time, so an archive-extracted-on-wrong-architecture is caught before the link step. * `apis/c/node/cmake/dora-api-config.cmake.in`, `apis/c/node/cmake/dora-api-version.cmake.in` — the generic cmake templates shared by all four crates (placeholders: `@PACKAGE@`, `@TARGET@`, `@LIB_UNIX@`, `@LIB_WIN@`, `@CXX_BRIDGE_FILES@`, `@VERSION@`). * `xtask/` — new workspace crate, `cargo run -p xtask -- stage <crate> <target_dir> <prefix>`, assembles the staging output produced by build.rs into a find_package-ready prefix directory. Handles both C-style (single staging dir under target_dir) and cxx-style (cmake config in cxxbridge tree, static lib in target_dir, cxxbridge .h/.cc also copied) layouts. Walks ancestor directories of `target_dir` to locate the cxxbridge tree, since the cxx tool always emits to `target/<triple>/cxxbridge/` while the static lib may be either `target/<profile>/` or `target/<triple>/<profile>/` depending on whether `--target` was passed. * `.github/workflows/test-c-cpp-libraries.yml` — new test workflow. Builds each C/C++ API crate, stages it via xtask, then runs `cmake configure + cmake build` against a checked-in fixture (`tests/cmake-find-package-c/`, `tests/cmake-find-package-cxx/`). Runs on ubuntu-22.04, macos-latest, windows-latest. Path-scoped so it only runs when the C/C++ surface changes. * `tests/cmake-find-package-c/`, `tests/cmake-find-package-cxx/` — tiny fixtures that exercise the find_package contract: minimal CMakeLists.txt + main.{c,cc} that take the address of a symbol from the dora C/C++ API. If the cmake config files are missing or the staging layout drifts, these fail at cmake configure or link time. * `.github/workflows/publish-c-cpp-libraries.yml` — staging step rewritten to delegate to `xtask stage` instead of carrying parallel Unix shell / pwsh `cp` blocks. Addresses @phil-opp's review concern from #1763 — staging now happens strictly *after* `cargo build` finishes the static lib, never during build.rs (where the .lib does not yet exist on a fresh Windows build). * `apis/C-CPP-LIBRARIES.md` — adds a "Recommended: find_package" section showing the canonical consumer recipe. Demotes the existing hand-rolled include/link-path examples to a "Legacy" section. Adds a "build from source with xtask" recipe so a local build produces the same layout consumers see in the GitHub release artefacts. What is NOT added (deliberately out of scope) ============================================= * No changes to `binaries/cli/src/template/{c,cxx}/*-cmake-template.txt`. Those templates (added by #1851 / rescue of #1514) use `ExternalProject_Add` against a source-tree checkout, which serves developers cloning the repo. The find_package idiom here serves the orthogonal "downloaded a release tarball" workflow. The two coexist: a future PR may add a `dora new --cmake find-package` flag that emits a find_package-style CMakeLists, but that is a separate UX decision. * No new public Rust API. The reply enum stays compatible. No semver- affecting type changes. * No CLI surface changes. `dora new --kind node --lang c/cxx` still emits the same template. * Phil's `cmake-templates.txt` duplication concern from #1763: inspected and confirmed not duplicative — the CLI template scaffolds into user projects (per-project CMakeLists), while `dora-api-config.cmake.in` is the package config consumed by find_package. Different layers. Verification ============ cargo fmt --all -- --check cargo clippy --all --exclude dora-{node-api,operator-api,ros2-bridge}-python -- -D warnings cargo test -p xtask -p dora-node-api-c -p dora-operator-api-c \ -p dora-node-api-cxx -p dora-operator-api-cxx cargo check --examples End-to-end find_package round-trip exercised locally on macos-aarch64: cargo build --release -p dora-node-api-c cargo run -p xtask -- stage dora-node-api-c target/release dora-c-prefix cmake -S tests/cmake-find-package-c -B build-c \ -DCMAKE_PREFIX_PATH=$(pwd)/dora-c-prefix cmake --build build-c # built smoke executable; exit 0 cargo build --release -p dora-node-api-cxx --target aarch64-apple-darwin cargo run -p xtask -- stage dora-node-api-cxx \ target/aarch64-apple-darwin/release \ dora-cpp-prefix cmake -S tests/cmake-find-package-cxx -B build-cxx \ -DCMAKE_PREFIX_PATH=$(pwd)/dora-cpp-prefix cmake --build build-cxx # built smoke executable; exit 0 CI test workflow drives the same recipe on linux/macos/windows. Co-authored-by: Ts-sound <Ts-sound@users.noreply.github.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-up of #1763) Adds CMake `find_package(dora-node-api-c)` / `find_package(dora-node-api-cxx)` support for consumers of the published static libraries, without disturbing #1851's `dora new --kind node --lang c/cxx` CLI templates (which serve the orthogonal source-tree-build workflow). Closes the residual piece of #1756 left over after #1763 was closed in favour of this narrower rescue. Co-authored-by @Ts-sound (tong), whose #1763 contributed the design and most of the code. What is added ============= * `apis/c/node/build.rs` (new), `apis/c/operator/build.rs`, `apis/c++/node/build.rs`, `apis/c++/operator/build.rs` — each build.rs now emits a `<crate>Config.cmake` + `<crate>ConfigVersion.cmake` at the standard `<prefix>/lib/cmake/<crate>/` layout, copies the public headers into `<prefix>/include/`, and for cxx crates also stages the generated `.cc` so consumers can compile it alongside their code. The config files import the static lib as a `<crate>::<crate>` target and an `<crate>::extra` interface target carrying the platform link dependencies (winapi libs / Apple frameworks / pthread+dl+m+rt) so downstream CMakeLists never have to list them by hand. Built-target vs current-target is checked at configure time, so an archive-extracted-on-wrong-architecture is caught before the link step. * `apis/c/node/cmake/dora-api-config.cmake.in`, `apis/c/node/cmake/dora-api-version.cmake.in` — the generic cmake templates shared by all four crates (placeholders: `@PACKAGE@`, `@TARGET@`, `@LIB_UNIX@`, `@LIB_WIN@`, `@CXX_BRIDGE_FILES@`, `@VERSION@`). * `xtask/` — new workspace crate, `cargo run -p xtask -- stage <crate> <target_dir> <prefix>`, assembles the staging output produced by build.rs into a find_package-ready prefix directory. Handles both C-style (single staging dir under target_dir) and cxx-style (cmake config in cxxbridge tree, static lib in target_dir, cxxbridge .h/.cc also copied) layouts. Walks ancestor directories of `target_dir` to locate the cxxbridge tree, since the cxx tool always emits to `target/<triple>/cxxbridge/` while the static lib may be either `target/<profile>/` or `target/<triple>/<profile>/` depending on whether `--target` was passed. * `.github/workflows/test-c-cpp-libraries.yml` — new test workflow. Builds each C/C++ API crate, stages it via xtask, then runs `cmake configure + cmake build` against a checked-in fixture (`tests/cmake-find-package-c/`, `tests/cmake-find-package-cxx/`). Runs on ubuntu-22.04, macos-latest, windows-latest. Path-scoped so it only runs when the C/C++ surface changes. * `tests/cmake-find-package-c/`, `tests/cmake-find-package-cxx/` — tiny fixtures that exercise the find_package contract: minimal CMakeLists.txt + main.{c,cc} that take the address of a symbol from the dora C/C++ API. If the cmake config files are missing or the staging layout drifts, these fail at cmake configure or link time. * `.github/workflows/publish-c-cpp-libraries.yml` — staging step rewritten to delegate to `xtask stage` instead of carrying parallel Unix shell / pwsh `cp` blocks. Addresses @phil-opp's review concern from #1763 — staging now happens strictly *after* `cargo build` finishes the static lib, never during build.rs (where the .lib does not yet exist on a fresh Windows build). * `apis/C-CPP-LIBRARIES.md` — adds a "Recommended: find_package" section showing the canonical consumer recipe. Demotes the existing hand-rolled include/link-path examples to a "Legacy" section. Adds a "build from source with xtask" recipe so a local build produces the same layout consumers see in the GitHub release artefacts. What is NOT added (deliberately out of scope) ============================================= * No changes to `binaries/cli/src/template/{c,cxx}/*-cmake-template.txt`. Those templates (added by #1851 / rescue of #1514) use `ExternalProject_Add` against a source-tree checkout, which serves developers cloning the repo. The find_package idiom here serves the orthogonal "downloaded a release tarball" workflow. The two coexist: a future PR may add a `dora new --cmake find-package` flag that emits a find_package-style CMakeLists, but that is a separate UX decision. * No new public Rust API. The reply enum stays compatible. No semver- affecting type changes. * No CLI surface changes. `dora new --kind node --lang c/cxx` still emits the same template. * Phil's `cmake-templates.txt` duplication concern from #1763: inspected and confirmed not duplicative — the CLI template scaffolds into user projects (per-project CMakeLists), while `dora-api-config.cmake.in` is the package config consumed by find_package. Different layers. Verification ============ cargo fmt --all -- --check cargo clippy --all --exclude dora-{node-api,operator-api,ros2-bridge}-python -- -D warnings cargo test -p xtask -p dora-node-api-c -p dora-operator-api-c \ -p dora-node-api-cxx -p dora-operator-api-cxx cargo check --examples End-to-end find_package round-trip exercised locally on macos-aarch64: cargo build --release -p dora-node-api-c cargo run -p xtask -- stage dora-node-api-c target/release dora-c-prefix cmake -S tests/cmake-find-package-c -B build-c \ -DCMAKE_PREFIX_PATH=$(pwd)/dora-c-prefix cmake --build build-c # built smoke executable; exit 0 cargo build --release -p dora-node-api-cxx --target aarch64-apple-darwin cargo run -p xtask -- stage dora-node-api-cxx \ target/aarch64-apple-darwin/release \ dora-cpp-prefix cmake -S tests/cmake-find-package-cxx -B build-cxx \ -DCMAKE_PREFIX_PATH=$(pwd)/dora-cpp-prefix cmake --build build-cxx # built smoke executable; exit 0 CI test workflow drives the same recipe on linux/macos/windows. Co-authored-by: Ts-sound <Ts-sound@users.noreply.github.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-up of #1763) Adds CMake `find_package(dora-node-api-c)` / `find_package(dora-node-api-cxx)` support for consumers of the published static libraries, without disturbing #1851's `dora new --kind node --lang c/cxx` CLI templates (which serve the orthogonal source-tree-build workflow). Closes the residual piece of #1756 left over after #1763 was closed in favour of this narrower rescue. Co-authored-by @Ts-sound (tong), whose #1763 contributed the design and most of the code. What is added ============= * `apis/c/node/build.rs` (new), `apis/c/operator/build.rs`, `apis/c++/node/build.rs`, `apis/c++/operator/build.rs` — each build.rs now emits a `<crate>Config.cmake` + `<crate>ConfigVersion.cmake` at the standard `<prefix>/lib/cmake/<crate>/` layout, copies the public headers into `<prefix>/include/`, and for cxx crates also stages the generated `.cc` so consumers can compile it alongside their code. The config files import the static lib as a `<crate>::<crate>` target and an `<crate>::extra` interface target carrying the platform link dependencies (winapi libs / Apple frameworks / pthread+dl+m+rt) so downstream CMakeLists never have to list them by hand. Built-target vs current-target is checked at configure time, so an archive-extracted-on-wrong-architecture is caught before the link step. * `apis/c/node/cmake/dora-api-config.cmake.in`, `apis/c/node/cmake/dora-api-version.cmake.in` — the generic cmake templates shared by all four crates (placeholders: `@PACKAGE@`, `@TARGET@`, `@LIB_UNIX@`, `@LIB_WIN@`, `@CXX_BRIDGE_FILES@`, `@VERSION@`). * `xtask/` — new workspace crate, `cargo run -p xtask -- stage <crate> <target_dir> <prefix>`, assembles the staging output produced by build.rs into a find_package-ready prefix directory. Handles both C-style (single staging dir under target_dir) and cxx-style (cmake config in cxxbridge tree, static lib in target_dir, cxxbridge .h/.cc also copied) layouts. Walks ancestor directories of `target_dir` to locate the cxxbridge tree, since the cxx tool always emits to `target/<triple>/cxxbridge/` while the static lib may be either `target/<profile>/` or `target/<triple>/<profile>/` depending on whether `--target` was passed. * `.github/workflows/test-c-cpp-libraries.yml` — new test workflow. Builds each C/C++ API crate, stages it via xtask, then runs `cmake configure + cmake build` against a checked-in fixture (`tests/cmake-find-package-c/`, `tests/cmake-find-package-cxx/`). Runs on ubuntu-22.04, macos-latest, windows-latest. Path-scoped so it only runs when the C/C++ surface changes. * `tests/cmake-find-package-c/`, `tests/cmake-find-package-cxx/` — tiny fixtures that exercise the find_package contract: minimal CMakeLists.txt + main.{c,cc} that take the address of a symbol from the dora C/C++ API. If the cmake config files are missing or the staging layout drifts, these fail at cmake configure or link time. * `.github/workflows/publish-c-cpp-libraries.yml` — staging step rewritten to delegate to `xtask stage` instead of carrying parallel Unix shell / pwsh `cp` blocks. Addresses @phil-opp's review concern from #1763 — staging now happens strictly *after* `cargo build` finishes the static lib, never during build.rs (where the .lib does not yet exist on a fresh Windows build). * `apis/C-CPP-LIBRARIES.md` — adds a "Recommended: find_package" section showing the canonical consumer recipe. Demotes the existing hand-rolled include/link-path examples to a "Legacy" section. Adds a "build from source with xtask" recipe so a local build produces the same layout consumers see in the GitHub release artefacts. What is NOT added (deliberately out of scope) ============================================= * No changes to `binaries/cli/src/template/{c,cxx}/*-cmake-template.txt`. Those templates (added by #1851 / rescue of #1514) use `ExternalProject_Add` against a source-tree checkout, which serves developers cloning the repo. The find_package idiom here serves the orthogonal "downloaded a release tarball" workflow. The two coexist: a future PR may add a `dora new --cmake find-package` flag that emits a find_package-style CMakeLists, but that is a separate UX decision. * No new public Rust API. The reply enum stays compatible. No semver- affecting type changes. * No CLI surface changes. `dora new --kind node --lang c/cxx` still emits the same template. * Phil's `cmake-templates.txt` duplication concern from #1763: inspected and confirmed not duplicative — the CLI template scaffolds into user projects (per-project CMakeLists), while `dora-api-config.cmake.in` is the package config consumed by find_package. Different layers. Verification ============ cargo fmt --all -- --check cargo clippy --all --exclude dora-{node-api,operator-api,ros2-bridge}-python -- -D warnings cargo test -p xtask -p dora-node-api-c -p dora-operator-api-c \ -p dora-node-api-cxx -p dora-operator-api-cxx cargo check --examples End-to-end find_package round-trip exercised locally on macos-aarch64: cargo build --release -p dora-node-api-c cargo run -p xtask -- stage dora-node-api-c target/release dora-c-prefix cmake -S tests/cmake-find-package-c -B build-c \ -DCMAKE_PREFIX_PATH=$(pwd)/dora-c-prefix cmake --build build-c # built smoke executable; exit 0 cargo build --release -p dora-node-api-cxx --target aarch64-apple-darwin cargo run -p xtask -- stage dora-node-api-cxx \ target/aarch64-apple-darwin/release \ dora-cpp-prefix cmake -S tests/cmake-find-package-cxx -B build-cxx \ -DCMAKE_PREFIX_PATH=$(pwd)/dora-cpp-prefix cmake --build build-cxx # built smoke executable; exit 0 CI test workflow drives the same recipe on linux/macos/windows. Co-authored-by: Ts-sound <Ts-sound@users.noreply.github.com> Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…-up of #1763) (#1875) Adds CMake `find_package(dora-node-api-c)` / `find_package(dora-node-api-cxx)` support for consumers of the published static libraries, without disturbing #1851's `dora new --kind node --lang c/cxx` CLI templates (which serve the orthogonal source-tree-build workflow). Closes the residual piece of #1756 left over after #1763 was closed in favour of this narrower rescue. Co-authored-by @Ts-sound (tong), whose #1763 contributed the design and most of the code. What is added ============= * `apis/c/node/build.rs` (new), `apis/c/operator/build.rs`, `apis/c++/node/build.rs`, `apis/c++/operator/build.rs` — each build.rs now emits a `<crate>Config.cmake` + `<crate>ConfigVersion.cmake` at the standard `<prefix>/lib/cmake/<crate>/` layout, copies the public headers into `<prefix>/include/`, and for cxx crates also stages the generated `.cc` so consumers can compile it alongside their code. The config files import the static lib as a `<crate>::<crate>` target and an `<crate>::extra` interface target carrying the platform link dependencies (winapi libs / Apple frameworks / pthread+dl+m+rt) so downstream CMakeLists never have to list them by hand. Built-target vs current-target is checked at configure time, so an archive-extracted-on-wrong-architecture is caught before the link step. * `apis/c/node/cmake/dora-api-config.cmake.in`, `apis/c/node/cmake/dora-api-version.cmake.in` — the generic cmake templates shared by all four crates (placeholders: `@PACKAGE@`, `@TARGET@`, `@LIB_UNIX@`, `@LIB_WIN@`, `@CXX_BRIDGE_FILES@`, `@VERSION@`). * `xtask/` — new workspace crate, `cargo run -p xtask -- stage <crate> <target_dir> <prefix>`, assembles the staging output produced by build.rs into a find_package-ready prefix directory. Handles both C-style (single staging dir under target_dir) and cxx-style (cmake config in cxxbridge tree, static lib in target_dir, cxxbridge .h/.cc also copied) layouts. Walks ancestor directories of `target_dir` to locate the cxxbridge tree, since the cxx tool always emits to `target/<triple>/cxxbridge/` while the static lib may be either `target/<profile>/` or `target/<triple>/<profile>/` depending on whether `--target` was passed. * `.github/workflows/test-c-cpp-libraries.yml` — new test workflow. Builds each C/C++ API crate, stages it via xtask, then runs `cmake configure + cmake build` against a checked-in fixture (`tests/cmake-find-package-c/`, `tests/cmake-find-package-cxx/`). Runs on ubuntu-22.04, macos-latest, windows-latest. Path-scoped so it only runs when the C/C++ surface changes. * `tests/cmake-find-package-c/`, `tests/cmake-find-package-cxx/` — tiny fixtures that exercise the find_package contract: minimal CMakeLists.txt + main.{c,cc} that take the address of a symbol from the dora C/C++ API. If the cmake config files are missing or the staging layout drifts, these fail at cmake configure or link time. * `.github/workflows/publish-c-cpp-libraries.yml` — staging step rewritten to delegate to `xtask stage` instead of carrying parallel Unix shell / pwsh `cp` blocks. Addresses @phil-opp's review concern from #1763 — staging now happens strictly *after* `cargo build` finishes the static lib, never during build.rs (where the .lib does not yet exist on a fresh Windows build). * `apis/C-CPP-LIBRARIES.md` — adds a "Recommended: find_package" section showing the canonical consumer recipe. Demotes the existing hand-rolled include/link-path examples to a "Legacy" section. Adds a "build from source with xtask" recipe so a local build produces the same layout consumers see in the GitHub release artefacts. What is NOT added (deliberately out of scope) ============================================= * No changes to `binaries/cli/src/template/{c,cxx}/*-cmake-template.txt`. Those templates (added by #1851 / rescue of #1514) use `ExternalProject_Add` against a source-tree checkout, which serves developers cloning the repo. The find_package idiom here serves the orthogonal "downloaded a release tarball" workflow. The two coexist: a future PR may add a `dora new --cmake find-package` flag that emits a find_package-style CMakeLists, but that is a separate UX decision. * No new public Rust API. The reply enum stays compatible. No semver- affecting type changes. * No CLI surface changes. `dora new --kind node --lang c/cxx` still emits the same template. * Phil's `cmake-templates.txt` duplication concern from #1763: inspected and confirmed not duplicative — the CLI template scaffolds into user projects (per-project CMakeLists), while `dora-api-config.cmake.in` is the package config consumed by find_package. Different layers. Verification ============ cargo fmt --all -- --check cargo clippy --all --exclude dora-{node-api,operator-api,ros2-bridge}-python -- -D warnings cargo test -p xtask -p dora-node-api-c -p dora-operator-api-c \ -p dora-node-api-cxx -p dora-operator-api-cxx cargo check --examples End-to-end find_package round-trip exercised locally on macos-aarch64: cargo build --release -p dora-node-api-c cargo run -p xtask -- stage dora-node-api-c target/release dora-c-prefix cmake -S tests/cmake-find-package-c -B build-c \ -DCMAKE_PREFIX_PATH=$(pwd)/dora-c-prefix cmake --build build-c # built smoke executable; exit 0 cargo build --release -p dora-node-api-cxx --target aarch64-apple-darwin cargo run -p xtask -- stage dora-node-api-cxx \ target/aarch64-apple-darwin/release \ dora-cpp-prefix cmake -S tests/cmake-find-package-cxx -B build-cxx \ -DCMAKE_PREFIX_PATH=$(pwd)/dora-cpp-prefix cmake --build build-cxx # built smoke executable; exit 0 CI test workflow drives the same recipe on linux/macos/windows. Co-authored-by: Ts-sound <Ts-sound@users.noreply.github.com> Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Summary
Add CMake
find_packagesupport for all C/C++ API crates (dora-node-api-c,dora-operator-api-c,dora-node-api-cxx,dora-operator-api-cxx), enabledora new --kind node --lang c/cxxand--kind dataflowto generate ready-to-build CMakeLists.txt, replace shell-based staging with a Rustxtasktool, and publish unified library archives with cmake config files.Problem
Running
dora new --kind node --lang cor--lang cxxproduced only source files without a build system. A// TODO: Makefile?comment remained in both template modules, requiring users to manually write their own build setup.Related
find_package#1756Solution
Generic CMake Template
Single
dora-api-config.cmake.inwith@PACKAGE@,@TARGET@,@LIB_UNIX@,@LIB_WIN@,@CXX_BRIDGE_FILES@placeholders shared by all 4 crates.build.rs Staging
Each crate's
build.rswrites cmake config + headers to predictable paths:target/<profile>/<crate>/lib/cmake/<crate>/*.cmake+include/*.htarget/cxxbridge/<crate>/lib/cmake/<crate>/*.cmake+include/*.h+src/*.ccxtask stage
Replaced shell scripts with
cargo run -p xtask -- stage <crate> <target_dir> <prefix>— cross-platform, handles all 4 crates.dora new Templates
--kind node --lang cnode.c+CMakeLists.txt(find_package(dora-node-api-c))--kind node --lang cxxnode.cc+CMakeLists.txt(find_package(dora-node-api-cxx)+CXX_BRIDGE_FILES)--kind dataflow --lang cCMakeLists.txt(find_package+add_subdirectory)--kind dataflow --lang cxxCMakeLists.txt(find_package+add_subdirectory+CXX_BRIDGE_FILES)Tests
test-c-cpp-libraries.yml: CI testscripts/c_cpp_lib/stage_test.sh— verifies staging for debug, release,--targetscripts/c_cpp_lib/build_node_test.sh—dora new --kind node+ cmake buildscripts/c_cpp_lib/build_dataflow_test.sh—dora new --kind dataflow+ cmake buildDocumentation
Rewrote
apis/C-CPP-LIBRARIES.mdwith Obtaining the API Libraries (download / xtask), Usingdora new, and CMake Integration sections.Key Changes
apis/c/node/cmake/dora-api-config.cmake.in— generic cmake templateapis/{c/operator,c++/node,c++/operator}/build.rs— cmake exportapis/c/{node,operator}/build.rs— stage totarget/<profile>/<crate>/xtask/—cargo run -p xtask -- stage <crate> <target_dir> <prefix>binaries/cli/src/template/c/{node,node/CMakeLists,cmake,mod}.rs— C node + dataflow templatesbinaries/cli/src/template/cxx/{node,node/CMakeLists,cmake,node-template,mod}.rs— C++ node + dataflow templates.github/workflows/{publish,test}-c-cpp-libraries.yml— replace shell scripts with xtaskscripts/c_cpp_lib/{stage_test,build_node_test,build_dataflow_test}.sh— build verificationapis/C-CPP-LIBRARIES.md— complete rewriteExpected Flow
Tasks
Notes
CXX_BRIDGE_FILESis only populated for C++ crates. C crates set it to empty..ccfiles are NOT included in the static library — they come fromfind_packageand must be compiled alongside user code.add_subdirectory()for each node, delegating to per-node CMakeLists.txt.