use cbindgen for FFI

This commit is contained in:
numzero 2026-08-22 01:38:43 +03:00
parent 1e8c440825
commit 068e2fb2e4
7 changed files with 64 additions and 22 deletions

View File

@ -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)

13
cbindgen.cmake Normal file
View File

@ -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()

14
ui/cbindgen.toml Normal file
View File

@ -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"]

View File

@ -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"
)

View File

@ -3,13 +3,6 @@
#include <stdexcept>
#include <utility>
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, {})) {
}

View File

@ -2,23 +2,10 @@
#include <cstdint>
#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 {

12
ui/src/types.hxx Normal file
View File

@ -0,0 +1,12 @@
#pragma once
struct alignas(16) Vec4 {
float x, y, z, w;
};
namespace ffi {
template <typename T>
using Box = T*;
} // namespace ffi