From dc69c25242ae73e33e618761169c34627b7e1217 Mon Sep 17 00:00:00 2001 From: Jonathan Schwender Date: Thu, 9 Mar 2023 13:31:53 +0100 Subject: [PATCH] Use cbindgen --depfile feature This allows us to regenerate the bindings only when necessary --- cmake/Corrosion.cmake | 30 ++++++++++++++----- test/cbindgen/CMakeLists.txt | 2 ++ test/cbindgen/rust2cpp/main.cpp | 3 ++ test/cbindgen/rust2cpp/rust/Cargo.lock | 9 ++++++ test/cbindgen/rust2cpp/rust/cbindgen.toml | 2 ++ test/cbindgen/rust2cpp/rust/src/ffi.rs | 3 ++ test/cbindgen/rust2cpp/rust/src/lib.rs | 3 ++ .../rust2cpp/rust/src/other_mod/mod.rs | 1 + 8 files changed, 45 insertions(+), 8 deletions(-) create mode 100644 test/cbindgen/rust2cpp/rust/src/ffi.rs create mode 100644 test/cbindgen/rust2cpp/rust/src/other_mod/mod.rs diff --git a/cmake/Corrosion.cmake b/cmake/Corrosion.cmake index 2a3be0b4..bfd91c08 100644 --- a/cmake/Corrosion.cmake +++ b/cmake/Corrosion.cmake @@ -1599,6 +1599,15 @@ between multiple invocations of this function. [cbindgen]: https://github.com/eqrion/cbindgen +### Current limitations + +- Cbindgens (optional) macro expansion feature internally actually builds the crate / runs the build script. + For this to work as expected in all cases, we probably need to set all the same environment variables + as when corrosion builds the crate. However the crate is a **library**, so we would need to figure out which + target builds it - and if there are multiple, potentially generate bindings per-target? + Alternatively we could add support of setting some environment variables on rlibs, and pulling that + information in when building the actual corrosion targets + Alternatively we could restrict corrosions support of this feature to actual imported staticlib/cdylib targets. ANCHOR_END: corrosion_cbindgen #]=======================================================================] function(corrosion_experimental_cbindgen) @@ -1672,6 +1681,8 @@ function(corrosion_experimental_cbindgen) set(corrosion_generated_dir "${CMAKE_CURRENT_BINARY_DIR}/corrosion_generated") set(generated_dir "${corrosion_generated_dir}/cbindgen/${rust_target}") set(header_placement_dir "${generated_dir}/include/") + set(depfile_placement_dir "${generated_dir}/depfile") + set(generated_depfile "${depfile_placement_dir}/${output_header_name}.d") set(generated_header "${header_placement_dir}/${output_header_name}") message(STATUS "rust target is ${rust_target}") if(CMAKE_VERSION VERSION_GREATER_EQUAL "3.23") @@ -1693,29 +1704,32 @@ function(corrosion_experimental_cbindgen) # This may be different from $header_placement_dir since the user specified HEADER_NAME may contain # relative directories. get_filename_component(generated_header_dir "${generated_header}" DIRECTORY) - file(MAKE_DIRECTORY ${generated_header_dir}) + file(MAKE_DIRECTORY "${generated_header_dir}") + + unset(depfile_cbindgen_arg) + unset(depfile_cmake_arg) + get_filename_component(generated_depfile_dir "${generated_depfile}" DIRECTORY) + file(MAKE_DIRECTORY "${generated_depfile_dir}") + set(depfile_cbindgen_arg "--depfile=${generated_depfile}") - # Todo: Add dependencies on the source Rust files here to get proper dependency rules (hard). - # For now we just specify a dummy file we won't generate as an additional output, so that the rule - # always runs. - # Future Options: a) upstream depfile creation into cbindgen, b) spider our way through the source-code ourselves. - # c) ask the user to specify the dependencies (in order to relax the rules). add_custom_command( OUTPUT - "${generated_header}" "${CMAKE_CURRENT_BINARY_DIR}/corrosion/non-existing-file.h" + "${generated_header}" COMMAND "${cbindgen}" --output "${generated_header}" --crate "${rust_target}" + ${depfile_cbindgen_arg} ${CCN_FLAGS} COMMENT "Generate cbindgen bindings for crate ${rust_target}" + DEPFILE "${generated_depfile}" COMMAND_EXPAND_LISTS WORKING_DIRECTORY "${package_manifest_dir}" ) if(NOT installed_cbindgen) add_custom_command( - OUTPUT "${generated_header}" "${CMAKE_CURRENT_BINARY_DIR}/corrosion/non-existing-file.h" + OUTPUT "${generated_header}" APPEND DEPENDS _corrosion_cbindgen ) diff --git a/test/cbindgen/CMakeLists.txt b/test/cbindgen/CMakeLists.txt index 86cabf5b..79566966 100644 --- a/test/cbindgen/CMakeLists.txt +++ b/test/cbindgen/CMakeLists.txt @@ -7,3 +7,5 @@ set_tests_properties(cbindgen_rust2cpp_run_cpp-exe PROPERTIES PASS_REGULAR_EXPRE # - A rust lib that is used by a rust executable # - cbindgen creates bindings for the rust-lib # - c++ code uses the rust lib and is used in turn by the rust bin. + +# todo: add a test for the DEPFILE and correct regenerating if the sources are touched. diff --git a/test/cbindgen/rust2cpp/main.cpp b/test/cbindgen/rust2cpp/main.cpp index 1085c4af..7ad201fc 100644 --- a/test/cbindgen/rust2cpp/main.cpp +++ b/test/cbindgen/rust2cpp/main.cpp @@ -16,4 +16,7 @@ int main(int argc, char **argv) { add_point(&p1, NULL); assert(p1.x == 100); assert(p1.y == 100); + + assert(OTHER_MOD_MAGIC_NUMBER == 192312312); + assert(FFI_MAGIC_NUMBER == 0xFDA00184); } diff --git a/test/cbindgen/rust2cpp/rust/Cargo.lock b/test/cbindgen/rust2cpp/rust/Cargo.lock index 5dc1732e..c7d8782b 100644 --- a/test/cbindgen/rust2cpp/rust/Cargo.lock +++ b/test/cbindgen/rust2cpp/rust/Cargo.lock @@ -1,5 +1,14 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. +version = 3 + +[[package]] +name = "other-crate" +version = "0.1.0" + [[package]] name = "rust-lib" version = "0.1.0" +dependencies = [ + "other-crate", +] diff --git a/test/cbindgen/rust2cpp/rust/cbindgen.toml b/test/cbindgen/rust2cpp/rust/cbindgen.toml index b358b7df..86b1a9ae 100644 --- a/test/cbindgen/rust2cpp/rust/cbindgen.toml +++ b/test/cbindgen/rust2cpp/rust/cbindgen.toml @@ -1,2 +1,4 @@ language = "C++" include_version = true + + diff --git a/test/cbindgen/rust2cpp/rust/src/ffi.rs b/test/cbindgen/rust2cpp/rust/src/ffi.rs new file mode 100644 index 00000000..01ad181c --- /dev/null +++ b/test/cbindgen/rust2cpp/rust/src/ffi.rs @@ -0,0 +1,3 @@ +//! Just a module that contains some entries that should be parsed by cbindgen. + +pub const FFI_MAGIC_NUMBER: u64 = 0xFDA0_0184; diff --git a/test/cbindgen/rust2cpp/rust/src/lib.rs b/test/cbindgen/rust2cpp/rust/src/lib.rs index 435c05f7..0ad5c8f8 100644 --- a/test/cbindgen/rust2cpp/rust/src/lib.rs +++ b/test/cbindgen/rust2cpp/rust/src/lib.rs @@ -1,5 +1,8 @@ pub const MAGIC_NUMBER: u64 = 0xABCD_EFAB; +pub mod ffi; +pub mod other_mod; + #[derive(Debug)] #[repr(C)] pub struct Point { diff --git a/test/cbindgen/rust2cpp/rust/src/other_mod/mod.rs b/test/cbindgen/rust2cpp/rust/src/other_mod/mod.rs new file mode 100644 index 00000000..ca34458b --- /dev/null +++ b/test/cbindgen/rust2cpp/rust/src/other_mod/mod.rs @@ -0,0 +1 @@ +pub const OTHER_MOD_MAGIC_NUMBER: u32 = 192312312;