From efec901634b3c9816f8788d48bf27c7511238855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sl=C3=A1vek=20Banko?= Date: Fri, 14 Jan 2022 04:12:30 +0100 Subject: [PATCH] tde_automoc: Add support for processing automoc for generated files. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Slávek Banko --- modules/TDEMacros.cmake | 42 +++++++++++++++++++++- modules/tde_automoc.cmake | 76 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 117 insertions(+), 1 deletion(-) create mode 100644 modules/tde_automoc.cmake diff --git a/modules/TDEMacros.cmake b/modules/TDEMacros.cmake index b438deb..9b46b84 100644 --- a/modules/TDEMacros.cmake +++ b/modules/TDEMacros.cmake @@ -498,13 +498,15 @@ macro( tde_automoc ) endforeach( ) if( NOT _found ) get_filename_component( _moc_file "${_moc_file}" NAME ) - tde_message_fatal( "AUTOMOC error: '${_moc_file}' cannot be generated.\n Reason: '${_src_file}.h' not found." ) + tde_message_fatal( "AUTOMOC error: '${_moc_file}' cannot be generated.\n Reason: '${_src_header}.h' not found." ) endif( ) endif( ) # moc-ing header + file( RELATIVE_PATH _moc_file_relative "${CMAKE_BINARY_DIR}" "${_moc_file}" ) add_custom_command( OUTPUT ${_moc_file} COMMAND ${TMOC_EXECUTABLE} ${_header_file} -o ${_moc_file} + COMMENT "Generating ${_moc_file_relative}" DEPENDS ${_header_file} ) # create dependency between source file and moc file @@ -514,6 +516,44 @@ macro( tde_automoc ) endif( _moc_includes ) + else( EXISTS "${_src_file}" ) + + # for generated file, the path must match the binary directory + string( LENGTH "${CMAKE_BINARY_DIR}" CMAKE_BINARY_DIR_LEN ) + string( LENGTH "${_src_file}" _basename_len ) + if( ${_basename_len} LESS ${CMAKE_BINARY_DIR_LEN} ) + set( _basedir_prefix "${CMAKE_SOURCE_DIR}" ) + else( ) + string( SUBSTRING "${_src_file}" 0 ${CMAKE_BINARY_DIR_LEN} _basedir_prefix ) + endif( ) + if( ${_basedir_prefix} STREQUAL "${CMAKE_BINARY_DIR}" ) + file( RELATIVE_PATH _sourcename "${CMAKE_BINARY_DIR}" "${_src_file}" ) + file( RELATIVE_PATH _basename "${CMAKE_CURRENT_BINARY_DIR}" "${_src_file}" ) + else( ) + file( RELATIVE_PATH _sourcename "${CMAKE_SOURCE_DIR}" "${_src_file}" ) + file( RELATIVE_PATH _basename "${CMAKE_CURRENT_SOURCE_DIR}" "${_src_file}" ) + endif( ) + + # automocing generated file + get_filename_component( _automoc_file "${_src_file}+automoc" NAME ) + set( _automoc_file "${CMAKE_CURRENT_BINARY_DIR}/${_automoc_file}" ) + + add_custom_command( OUTPUT ${_automoc_file} + COMMAND ${CMAKE_COMMAND} + -DTMOC_EXECUTABLE:FILEPATH=${TMOC_EXECUTABLE} + -DSRC_FILE:FILEPATH=${CMAKE_CURRENT_BINARY_DIR}/${_basename} + -DMETA_INCLUDES:STRING="${_meta_includes}" + -DMASTER_SOURCE_DIR:FILEPATH=${CMAKE_SOURCE_DIR} + -DMASTER_BINARY_DIR:FILEPATH=${CMAKE_BINARY_DIR} + -P ${TDE_CMAKE_MODULES}/tde_automoc.cmake + COMMENT "Automocing ${_sourcename}" + DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/${_basename}" + ) + + # create dependency between source file and moc file + set_property( SOURCE "${CMAKE_CURRENT_BINARY_DIR}/${_basename}" + APPEND PROPERTY OBJECT_DEPENDS ${_automoc_file} ) + endif( EXISTS "${_src_file}" ) endforeach( _src_file ) diff --git a/modules/tde_automoc.cmake b/modules/tde_automoc.cmake new file mode 100644 index 0000000..7a7c23a --- /dev/null +++ b/modules/tde_automoc.cmake @@ -0,0 +1,76 @@ +################################################# +# +# (C) 2022 Slávek Banko +# slavek (DOT) banko (AT) axis.cz +# +# Improvements and feedback are welcome +# +# This file is released under GPL >= 2 +# +################################################# + +if( NOT ${CMAKE_CURRENT_LIST_DIR} STREQUAL ${CMAKE_ROOT}/Modules ) + set( CMAKE_MODULE_PATH "${CMAKE_CURRENT_LIST_DIR}" ) +endif() +include( TDEMacros ) + + +get_filename_component( _src_file "${SRC_FILE}" ABSOLUTE ) +set( _meta_includes ${META_INCLUES} ) +unset( _moc_headers ) + +if( EXISTS "${_src_file}" ) + + # read source file and check if have moc include + file( READ "${_src_file}" _src_content ) + string( REGEX MATCHALL "#include +[^ ]+\\.moc[\">]" _moc_includes "${_src_content}" ) + + # found included moc(s)? + if( _moc_includes ) + foreach( _moc_file ${_moc_includes} ) + + # extracting moc filename + string( REGEX MATCH "[^ <\"]+\\.moc" _moc_file "${_moc_file}" ) + set( _moc_file "${CMAKE_CURRENT_BINARY_DIR}/${_moc_file}" ) + + # create header filename + get_filename_component( _src_path "${_src_file}" ABSOLUTE ) + get_filename_component( _src_path "${_src_path}" PATH ) + get_filename_component( _src_header "${_moc_file}" NAME_WE ) + set( _header_file "${_src_path}/${_src_header}.h" ) + + # if header doesn't exists, check in META_INCLUDES + if( NOT EXISTS "${_header_file}" ) + unset( _found ) + foreach( _src_path ${_meta_includes} ) + set( _header_file "${_src_path}/${_src_header}.h" ) + if( EXISTS "${_header_file}" ) + set( _found 1 ) + break( ) + endif( ) + endforeach( ) + if( NOT _found ) + get_filename_component( _moc_file "${_moc_file}" NAME ) + tde_message_fatal( "AUTOMOC error: '${_moc_file}' cannot be generated.\n Reason: '${_src_header}.h' not found." ) + endif( ) + endif( ) + + # moc-ing header + execute_process( COMMAND ${TMOC_EXECUTABLE} ${_header_file} -o ${_moc_file} ) + list( APPEND _moc_headers "${_src_header}.h" ) + + endforeach( _moc_file ) + + endif( _moc_includes ) + +else() + tde_message_fatal( "AUTOMOC error: '${_src_file}' not found!" ) +endif( EXISTS "${_src_file}" ) + +get_filename_component( _automoc_file "${_src_file}+automoc" NAME ) +if( DEFINED _moc_headers ) + string( REPLACE ";" "\n * " _moc_headers "${_moc_headers}" ) + file( WRITE "${_automoc_file}" "/*\n * processed:\n * ${_moc_headers}\n */" ) +else() + file( WRITE "${_automoc_file}" "/* processed - no moc files */" ) +endif()