From 068e2fb2e40b6fdfba030469ecc8cc7c246b5596 Mon Sep 17 00:00:00 2001 From: numzero Date: Sat, 22 Aug 2026 01:38:43 +0300 Subject: [PATCH] use cbindgen for FFI --- CMakeLists.txt | 2 ++ cbindgen.cmake | 13 +++++++++++++ ui/cbindgen.toml | 14 ++++++++++++++ ui/impl.cmake | 21 +++++++++++++++++++++ ui/src/api.cxx | 7 ------- ui/src/api.hxx | 17 ++--------------- ui/src/types.hxx | 12 ++++++++++++ 7 files changed, 64 insertions(+), 22 deletions(-) create mode 100644 cbindgen.cmake create mode 100644 ui/cbindgen.toml create mode 100644 ui/src/types.hxx diff --git a/CMakeLists.txt b/CMakeLists.txt index 61bc0df..e4e9092 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -9,6 +9,8 @@ find_package(Qt6 REQUIRED COMPONENTS Gui Widgets) find_program(CARGO cargo REQUIRED) set(CARGO_TARGET_DIR "${CMAKE_BINARY_DIR}/cargo") +include(cbindgen.cmake) + qt_standard_project_setup() add_subdirectory(ui) diff --git a/cbindgen.cmake b/cbindgen.cmake new file mode 100644 index 0000000..f0d4a7c --- /dev/null +++ b/cbindgen.cmake @@ -0,0 +1,13 @@ +option(LOCAL_CBINDGEN "Download and build `cbindgen` even if one can be found on the system") + +if(NOT LOCAL_CBINDGEN) + find_program(CBINDGEN cbindgen) +endif() + +if(NOT CBINDGEN) + message(CONFIGURE_LOG "cbindgen not found, downloading...") + set(crates "${CMAKE_BINARY_DIR}/crates") + file(MAKE_DIRECTORY ${crates}) + execute_process(COMMAND ${CARGO} install --root ${crates} cbindgen@0.29.4) + set(CACHE{CBINDGEN} TYPE FILEPATH FORCE VALUE "${crates}/bin/cbindgen") +endif() diff --git a/ui/cbindgen.toml b/ui/cbindgen.toml new file mode 100644 index 0000000..3321c4d --- /dev/null +++ b/ui/cbindgen.toml @@ -0,0 +1,14 @@ +includes = ["types.hxx"] +sys_includes = ["cstdint"] +pragma_once = true +no_includes = true +namespace = "ffi" +tab_width = 4 +language = "C++" + +[parse] +parse_deps = true +include = ["PROJECT-NAME"] + +[export] +exclude = ["Box"] diff --git a/ui/impl.cmake b/ui/impl.cmake index ff00ffc..b2b758b 100644 --- a/ui/impl.cmake +++ b/ui/impl.cmake @@ -22,3 +22,24 @@ add_library(PROJECT_NAME_impl STATIC IMPORTED) set_target_properties(PROJECT_NAME_impl PROPERTIES IMPORTED_LOCATION ${impl_basename}.a ) + +# generate the bindings +file(MAKE_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/include") +set(bindings_basename "${CMAKE_CURRENT_BINARY_DIR}/include/bindings") + +add_custom_command( + OUTPUT ${bindings_basename}.hxx + COMMAND ${CBINDGEN} --only-target-dependencies --output "${bindings_basename}.hxx" --depfile "${bindings_basename}.d" + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + DEPFILE ${bindings_basename}.d + VERBATIM + CODEGEN + DEPENDS_EXPLICIT_ONLY +) + +target_sources(PROJECT_NAME_impl INTERFACE + ${bindings_basename}.hxx +) +target_include_directories(PROJECT_NAME_impl INTERFACE + "${CMAKE_CURRENT_BINARY_DIR}/include" +) diff --git a/ui/src/api.cxx b/ui/src/api.cxx index aaa2b64..5b8e689 100644 --- a/ui/src/api.cxx +++ b/ui/src/api.cxx @@ -3,13 +3,6 @@ #include #include -namespace ffi { -extern "C" Core* rt4_viewport_create(xcb_connection_t* connection, std::uint32_t window, std::uint32_t width, std::uint32_t height); -extern "C" void rt4_viewport_destroy(Core* viewport); -extern "C" void rt4_viewport_configure(Core* viewport, std::uint32_t width, std::uint32_t height); -extern "C" void rt4_viewport_redraw(Core* viewport, const RedrawArgs* args); -} // namespace ffi - BoxCore::BoxCore(BoxCore&& b) : ptr(std::exchange(b.ptr, {})) { } diff --git a/ui/src/api.hxx b/ui/src/api.hxx index 82d9880..4847123 100644 --- a/ui/src/api.hxx +++ b/ui/src/api.hxx @@ -2,23 +2,10 @@ #include +#include "bindings.hxx" + struct xcb_connection_t; -struct alignas(16) Vec4 { - float x, y, z, w; -}; - -namespace ffi { -struct Core; - -struct RedrawArgs { - float cam_yaw; - float cam_pitch; - float cam_distance; - float cam_fovy; -}; -} // namespace ffi - using ffi::RedrawArgs; class MutCore { diff --git a/ui/src/types.hxx b/ui/src/types.hxx new file mode 100644 index 0000000..b8b5b73 --- /dev/null +++ b/ui/src/types.hxx @@ -0,0 +1,12 @@ +#pragma once + +struct alignas(16) Vec4 { + float x, y, z, w; +}; + +namespace ffi { + +template +using Box = T*; + +} // namespace ffi