Skip to content

Commit c440acd

Browse files
committed
cmake: rust: Compile the bindgen wrapper
When compiling Rust programs, the bindgen utility generates a wrapper file to expand inline functions, as these otherwise cannot be accessed from rust. Pass a consistent name to the cargo build, and add it to our source build so that this wrapper get compiled. Signed-off-by: David Brown <[email protected]>
1 parent 8dc7715 commit c440acd

File tree

1 file changed

+32
-2
lines changed

1 file changed

+32
-2
lines changed

cmake/modules/rust.cmake

Lines changed: 32 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -49,12 +49,28 @@ function(_rust_map_target)
4949
endif()
5050
endfunction()
5151

52+
function(get_include_dirs target dirs)
53+
get_target_property(include_dirs ${target} INTERFACE_INCLUDE_DIRECTORIES)
54+
if(include_dirs)
55+
set(${dirs} ${include_dirs} PARENT_SCOPE)
56+
else()
57+
set(${dirs} "" PARENT_SCOPE)
58+
endif()
59+
endfunction()
60+
5261
function(rust_cargo_application)
5362
# For now, hard-code the Zephyr crate directly here. Once we have
5463
# more than one crate, these should be added by the modules
5564
# themselves.
5665
set(LIB_RUST_CRATES zephyr zephyr-build)
5766

67+
get_include_dirs(zephyr_interface include_dirs)
68+
69+
get_target_property(include_dirs, zephyr_interface INTERFACE_INCLUDE_DIRECTORIES)
70+
get_property(include_defines TARGET zephyr_interface PROPERTY INTERFACE_COMPILE_DEFINITIONS)
71+
message(STATUS "Includes: ${include_dirs}")
72+
message(STATUS "Defines: ${include_defines}")
73+
5874
_rust_map_target()
5975
message(STATUS "Building Rust llvm target ${RUST_TARGET}")
6076

@@ -68,6 +84,10 @@ function(rust_cargo_application)
6884
set(RUST_LIBRARY "${CARGO_TARGET_DIR}/${RUST_TARGET}/${RUST_BUILD_TYPE}/librustapp.a")
6985
set(SAMPLE_CARGO_CONFIG "${CMAKE_CURRENT_BINARY_DIR}/rust/sample-cargo-config.toml")
7086

87+
# The generated C binding wrappers. These are bindgen-generated wrappers for the inline functions
88+
# within Zephyr.
89+
set(WRAPPER_FILE "${CMAKE_CURRENT_BINARY_DIR}/rust/wrapper.c")
90+
7191
# To get cmake to always invoke Cargo requires a bit of a trick. We make the output of the
7292
# command a file that never gets created. This will cause cmake to always rerun cargo. We
7393
# add the actual library as a BYPRODUCTS list of this command, otherwise, the first time the
@@ -109,6 +129,9 @@ target-dir = \"${CARGO_TARGET_DIR}\"
109129
BUILD_DIR = \"${CMAKE_CURRENT_BINARY_DIR}\"
110130
DOTCONFIG = \"${DOTCONFIG}\"
111131
ZEPHYR_DTS = \"${ZEPHYR_DTS}\"
132+
INCLUDE_DIRS = \"${include_dirs}\"
133+
INCLUDE_DEFINES = \"${include_defines}\"
134+
WRAPPER_FILE = \"${WRAPPER_FILE}\"
112135
113136
[patch.crates-io]
114137
${config_paths}
@@ -117,12 +140,15 @@ ${config_paths}
117140
# The library is built by invoking Cargo.
118141
add_custom_command(
119142
OUTPUT ${DUMMY_FILE}
120-
BYPRODUCTS ${RUST_LIBRARY}
143+
BYPRODUCTS ${RUST_LIBRARY} ${WRAPPER_FILE}
121144
COMMAND
122145
${CMAKE_EXECUTABLE}
123146
env BUILD_DIR=${CMAKE_CURRENT_BINARY_DIR}
124147
DOTCONFIG=${DOTCONFIG}
125148
ZEPHYR_DTS=${ZEPHYR_DTS}
149+
INCLUDE_DIRS="${include_dirs}"
150+
INCLUDE_DEFINES="${include_defines}"
151+
WRAPPER_FilE="${WRAPPER_FILE}"
126152
cargo build
127153
# TODO: release flag if release build
128154
# --release
@@ -151,5 +177,9 @@ ${config_paths}
151177

152178
# Presumably, Rust applications will have no C source files, but cmake will require them.
153179
# Add an empty file so that this will build. The main will come from the rust library.
154-
target_sources(app PRIVATE ${ZEPHYR_BASE}/lib/rust/main.c)
180+
target_sources(app PRIVATE ${ZEPHYR_BASE}/lib/rust/main.c ${WRAPPER_FILE})
181+
set_source_files_properties(
182+
${WRAPPER_FILE}
183+
COMPILE_FLAGS "-I${ZEPHYR_BASE}/lib/rust/zephyr-sys"
184+
)
155185
endfunction()

0 commit comments

Comments
 (0)