diff --git a/CMakeLists.txt b/CMakeLists.txt index a52f0de..0f981aa 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -11,6 +11,7 @@ include(Meta) include(Sysroot) include(BSP) include(Arch) +include(Msg-Interface) include(Templates) bsp_reset() diff --git a/cmake/Msg-Interface.cmake b/cmake/Msg-Interface.cmake new file mode 100644 index 0000000..cc92f53 --- /dev/null +++ b/cmake/Msg-Interface.cmake @@ -0,0 +1,75 @@ +find_program(IFC + NAMES ifc + REQUIRED + HINTS ${BUILD_TOOLS_DIR}) +message(STATUS "Found interface compiler: ${IFC}") + +function(add_interface) + set(options) + set(one_value_args NAME PARENT_DIR PATH) + set(multi_value_args) + + cmake_parse_arguments(PARSE_ARGV 0 arg + "${options}" + "${one_value_args}" + "${multi_value_args}") + + message(STATUS "Building interface ${arg_NAME}") + file(MAKE_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${arg_PARENT_DIR}) + set(header_path ${CMAKE_CURRENT_BINARY_DIR}/${arg_PARENT_DIR}/${arg_NAME}.h) + + add_custom_command( + OUTPUT ${header_path} + COMMAND ${IFC} ${arg_PATH} + WORKING_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/${arg_PARENT_DIR} + COMMENT "Compiling interface: ${arg_NAME}") + + add_custom_target(ifgen-${arg_NAME} ALL + DEPENDS ${header_path}) + + set_target_properties(ifgen-${arg_NAME} PROPERTIES + iface_header_path ${header_path} + iface_parent_dir ${arg_PARENT_DIR}) + + add_library(iflib-${arg_NAME} INTERFACE) + set_target_properties(iflib-${arg_NAME} PROPERTIES + INTERFACE_INCLUDE_DIRECTORIES ${CMAKE_CURRENT_BINARY_DIR}) + add_dependencies(iflib-${arg_NAME} ifgen-${arg_NAME}) + add_library(interface::${arg_NAME} ALIAS iflib-${arg_NAME}) +endfunction(add_interface) + +function(iface_get_header_path) + set(options) + set(one_value_args NAME OUT) + set(multi_value_args) + + cmake_parse_arguments(PARSE_ARGV 0 arg + "${options}" + "${one_value_args}" + "${multi_value_args}") + + get_property( + value + TARGET ifgen-${name} + PROPERTY iface_header_path) + + set(${arg_OUT} ${value} PARENT_SCOPE) +endfunction(iface_get_header_path) + +function(iface_get_parent_dir) + set(options) + set(one_value_args NAME OUT) + set(multi_value_args) + + cmake_parse_arguments(PARSE_ARGV 0 arg + "${options}" + "${one_value_args}" + "${multi_value_args}") + + get_property( + value + TARGET ifgen-${name} + PROPERTY iface_parent_dir) + + set(${arg_OUT} ${value} PARENT_SCOPE) +endfunction(iface_get_parent_dir) diff --git a/cmake/Sysroot.cmake b/cmake/Sysroot.cmake index 01289e1..5aa01cb 100644 --- a/cmake/Sysroot.cmake +++ b/cmake/Sysroot.cmake @@ -186,6 +186,37 @@ function(sysroot_add_file) set_property(GLOBAL PROPERTY sysroot_target_list ${sysroot_targets} ${sysroot_target_name}) endfunction(sysroot_add_file) +function(sysroot_add_interface) + set(options) + set(one_value_args NAME DEST_DIR) + set(multi_value_args DEPENDS) + + cmake_parse_arguments(PARSE_ARGV 0 arg + "${options}" + "${one_value_args}" + "${multi_value_args}") + + iface_get_header_path(NAME ${arg_NAME} OUT src_path) + iface_get_parent_dir(NAME ${arg_NAME} OUT parent_dir) + set(dest_dir ${arg_DEST_DIR}/${parent_dir}) + set(sysroot_target_name _sysroot-iface-${arg_NAME}) + + get_property(sysroot_targets GLOBAL PROPERTY sysroot_target_list) + list(LENGTH sysroot_targets nr_sysroot_targets) + if (${nr_sysroot_targets} GREATER 0) + math(EXPR serialiser_index "${nr_sysroot_targets}-1") + list(GET sysroot_targets ${serialiser_index} serialiser) + endif () + + add_custom_target(${sysroot_target_name} + COMMAND ${Python_EXECUTABLE} ${sysroot_tool} + add-binary ${sysroot_manifest} ${arg_NAME} + ${dest_dir} ${src_path} + COMMENT "Preparing sysroot component: ${arg_ID}" + DEPENDS ifgen-${arg_NAME} ${serialiser} ${arg_DEPENDS}) + + set_property(GLOBAL PROPERTY sysroot_target_list ${sysroot_targets} ${sysroot_target_name}) +endfunction(sysroot_add_interface) function(sysroot_finalise) get_property(sysroot_targets GLOBAL PROPERTY sysroot_target_list)