149 lines
7.2 KiB
CMake
149 lines
7.2 KiB
CMake
|
|
# =============================================================================
|
|
# first, get some info about the compiler (and bindgen)
|
|
|
|
# get rustc binary
|
|
if(NOT DEFINED RUSTC_BIN OR "${RUSTC_BIN}" STREQUAL "")
|
|
find_program(RUSTC_BIN rustc REQUIRED)
|
|
endif()
|
|
set(RUSTC_BIN ${RUSTC_BIN} CACHE FILEPATH "rustc command")
|
|
message(NOTICE "-- RUSTC_BIN is ${RUSTC_BIN}")
|
|
|
|
# get cbindgen binary
|
|
if(NOT DEFINED CBINDGEN_BIN OR "${CBINDGEN_BIN}" STREQUAL "")
|
|
find_program(CBINDGEN_BIN cbindgen REQUIRED)
|
|
endif()
|
|
set(CBINDGEN_BIN ${CBINDGEN_BIN} CACHE FILEPATH "cbindgen command")
|
|
message(NOTICE "-- CBINDGEN_BIN is ${CBINDGEN_BIN}")
|
|
|
|
# get bindgen binary
|
|
if(NOT DEFINED BINDGEN_BIN OR "${BINDGEN_BIN}" STREQUAL "")
|
|
find_program(BINDGEN_BIN bindgen REQUIRED)
|
|
endif()
|
|
set(BINDGEN_BIN ${BINDGEN_BIN} CACHE FILEPATH "bindgen command")
|
|
message(NOTICE "-- BINDGEN_BIN is ${BINDGEN_BIN}")
|
|
|
|
# =============================================================================
|
|
# set compile options
|
|
|
|
if(DEFINED RUST_TARGET)
|
|
list(APPEND RUST_CFLAGS "--target=${RUST_TARGET}")
|
|
endif()
|
|
if(DEFINED RUST_CPU)
|
|
list(APPEND RUST_CFLAGS "-C" "target-cpu=${RUST_CPU}")
|
|
endif()
|
|
if(CMAKE_BUILD_TYPE STREQUAL Debug)
|
|
list(APPEND RUST_CFLAGS "-C" "opt-level=0" "-g")
|
|
elseif(CMAKE_BUILD_TYPE STREQUAL Release)
|
|
list(APPEND RUST_CFLAGS "-C" "opt-level=3")
|
|
elseif(CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo)
|
|
list(APPEND RUST_CFLAGS "-C" "opt-level=2" "-g")
|
|
elseif(CMAKE_BUILD_TYPE STREQUAL MinSizeRel)
|
|
list(APPEND RUST_CFLAGS "-C" "opt-level=z")
|
|
endif()
|
|
|
|
list(APPEND BINDGEN_CFLAGS "--explicit-padding" "--formatter=none")
|
|
|
|
list(APPEND CBINDGEN_CFLAGS "--cpp-compat" "-l" "C")
|
|
if(CMAKE_BUILD_TYPE STREQUAL Debug)
|
|
list(APPEND CBINDGEN_CFLAGS "--profile" "Debug")
|
|
elseif(CMAKE_BUILD_TYPE STREQUAL Release OR CMAKE_BUILD_TYPE STREQUAL RelWithDebInfo OR CMAKE_BUILD_TYPE STREQUAL MinSizeRel)
|
|
list(APPEND CBINDGEN_CFLAGS "--profile" "Release")
|
|
endif()
|
|
|
|
# =============================================================================
|
|
# now define the macro we'll be using
|
|
|
|
function(add_rust_object TOP_PROJECT RUST_TOP_SOURCE_FILE)
|
|
if(ARGC GREATER 3)
|
|
set(TARGET_NAME ${ARGV3})
|
|
else()
|
|
cmake_path(GET RUST_TOP_SOURCE_FILE STEM TARGET_NAME)
|
|
endif()
|
|
|
|
# directory the header file will be in
|
|
file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/)
|
|
|
|
### C-to-rust bindings (generate .rs from C headers, bindgen)
|
|
set(HEADER_PATH "")
|
|
set(MAIN_RUST_DEP "")
|
|
|
|
if(ARGC GREATER 2)
|
|
set(HEADER_PATH ${ARGV2})
|
|
cmake_path(GET HEADER_PATH STEM HEADER_NAME)
|
|
|
|
if(NOT(HEADER_PATH STREQUAL ""))
|
|
# generate rs from c headers
|
|
if("--use-core" IN_LIST BINDGEN_CFLAGS)
|
|
add_custom_command(
|
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${HEADER_NAME}_bindgen.rs
|
|
COMMAND ${BINDGEN_BIN} ${BINDGEN_CFLAGS} --depfile ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${HEADER_NAME}_bindgen.rs.d -o ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${HEADER_NAME}_bindgen.rs.tmp ${HEADER_PATH}
|
|
COMMAND python -c "import sys;f=open\(sys.argv[1]+'.tmp','r'\).read\(\);open\(sys.argv[1],'w'\).write\('#![no_std]'+chr(10)+f\)" ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${HEADER_NAME}_bindgen.rs
|
|
BYPRODUCTS ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${HEADER_NAME}_bindgen.rs.tmp
|
|
DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${HEADER_NAME}_bindgen.rs.d
|
|
MAIN_DEPENDENCY ${RUST_TOP_SOURCE_FILE}
|
|
VERBATIM
|
|
)
|
|
else()
|
|
add_custom_command(
|
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${HEADER_NAME}_bindgen.rs
|
|
COMMAND ${BINDGEN_BIN} ${BINDGEN_CFLAGS} --depfile ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${HEADER_NAME}_bindgen.rs.d -o ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${HEADER_NAME}_bindgen.rs ${HEADER_PATH}
|
|
DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${HEADER_NAME}_bindgen.rs.d
|
|
MAIN_DEPENDENCY ${RUST_TOP_SOURCE_FILE}
|
|
VERBATIM
|
|
)
|
|
endif()
|
|
add_custom_target(c2rs_${TARGET_NAME}_src_tgt DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${HEADER_NAME}_bindgen.rs)
|
|
|
|
# build crate from it so we can actually import it
|
|
add_custom_command(
|
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/lib${HEADER_NAME}_bindgen.rlib
|
|
COMMAND ${RUSTC_BIN} ${RUST_CFLAGS} --crate-type=rlib --emit=link,dep-info=${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/lib${HEADER_NAME}_bindgen.rlib.d -o ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/lib${HEADER_NAME}_bindgen.rlib ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${HEADER_NAME}_bindgen.rs
|
|
DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/lib${HEADER_NAME}_bindgen.rlib.d
|
|
MAIN_DEPENDENCY ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${HEADER_NAME}_bindgen.rs
|
|
VERBATIM
|
|
)
|
|
add_custom_target(c2rs_${TARGET_NAME}_tgt DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/lib${HEADER_NAME}_bindgen.rlib)
|
|
add_library(c2rs_${TARGET_NAME} OBJECT $<TARGET_PROPERTY:c2rs_${TARGET_NAME}_tgt,SOURCES>)
|
|
list(APPEND RUST_CFLAGS "--extern" "${HEADER_NAME}_bindgen=${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/lib${HEADER_NAME}_bindgen.rlib")
|
|
|
|
set(MAIN_RUST_DEP "c2rs_${TARGET_NAME}_tgt")
|
|
endif()
|
|
endif()
|
|
|
|
### rust-to-C bindings (generate C headers from .rs, cbindgen)
|
|
# cbindgen call
|
|
add_custom_command(
|
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${TARGET_NAME}.h
|
|
COMMAND ${CBINDGEN_BIN} ${CBINDGEN_CFLAGS} -d --depfile ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${TARGET_NAME}.h.d -o ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${TARGET_NAME}.h ${RUST_TOP_SOURCE_FILE}
|
|
DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${TARGET_NAME}.h.d
|
|
MAIN_DEPENDENCY ${RUST_TOP_SOURCE_FILE}
|
|
VERBATIM
|
|
)
|
|
# make a virtual library for the header files
|
|
add_library(rs2c_${TARGET_NAME} INTERFACE ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/${TARGET_NAME}.h)
|
|
|
|
# add dependency to ensure build order and stuff
|
|
target_link_libraries(${TOP_PROJECT} rs2c_${TARGET_NAME})
|
|
# and add include directories
|
|
target_include_directories(${TOP_PROJECT} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/)
|
|
|
|
### rust compilation
|
|
# the compile command
|
|
add_custom_command(
|
|
OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.obj
|
|
COMMAND ${RUSTC_BIN} ${RUST_CFLAGS} --emit=obj,dep-info=${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.obj.d --crate-type=staticlib -o ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.obj ${RUST_TOP_SOURCE_FILE}
|
|
DEPFILE ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.obj.d
|
|
# ensures the bindgen happens before the rustc compilation
|
|
#DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/generated/rust_${TARGET_NAME}/lib${TARGET_NAME}_bindgen.rlib
|
|
DEPENDS ${MAIN_RUST_DEP}
|
|
MAIN_DEPENDENCY ${RUST_TOP_SOURCE_FILE}
|
|
VERBATIM
|
|
)
|
|
# add a virtual library that can be reused and referred to (not possible with a bare add_custom_command())
|
|
add_library(${TARGET_NAME} OBJECT ${CMAKE_CURRENT_BINARY_DIR}/${TARGET_NAME}.obj)
|
|
# add generated object file from the library to the code to compile
|
|
target_sources(${TOP_PROJECT} PUBLIC $<TARGET_PROPERTY:${TARGET_NAME},SOURCES>)
|
|
endfunction()
|
|
|