################################################# # # # Auxiliary macros for TQt # # # ################################################# include( TDEMacros ) ################################################# ##### ##### tqt_requires ##### ##### Asserts that if opt1 is set opt2 is set also ##### ##### Syntax: ##### tqt_requires( opt1 opt2 ) macro( tqt_requires _opt1 _opt2 ) if( ${_opt1} AND NOT ${_opt2} ) tde_message_fatal( "${_opt1}=ON requires ${_opt2}=ON to build" ) endif( ) endmacro( tqt_requires ) ################################################# ##### ##### tqt_install_includes ##### ##### The macro is used to determine the headers that are installed, ##### while the symlinks in the binary include directory are created. ##### ##### Syntax: ##### tqt_install_includes( ##### [FILES] include_name [include_name] ##### [DESTINATION subdir] ##### [ONLY_SYMLINK] ##### ) macro( tqt_install_includes ) unset( _files ) unset( _dest ) unset( _only_symlink ) set( _var _files ) foreach( _arg ${ARGN} ) # found directive "FILES" if( "+${_arg}" STREQUAL "+FILES" ) unset( _files ) set( _var _files ) set( _directive 1 ) endif( ) # found directive "DESTINATION" if( "+${_arg}" STREQUAL "+DESTINATION" ) unset( _dest ) set( _var _dest ) set( _directive 1 ) endif( ) # found directive "ONLY_SYMLINK" if( "+${_arg}" STREQUAL "+ONLY_SYMLINK" ) unset( _var ) set( _only_symlink 1 ) set( _directive 1 ) endif( ) # collect data if( _directive ) unset( _directive ) elseif( _var ) list( APPEND ${_var} ${_arg} ) endif( ) endforeach( ) # determine destination directory if( NOT IS_ABSOLUTE( "${_dest}" ) ) set( _dest "${QT_INSTALL_HEADERS}/${_dest}" ) endif() file( RELATIVE_PATH _dest_sub "${QT_INSTALL_HEADERS}" "${_dest}" ) file( MAKE_DIRECTORY "${CMAKE_BINARY_DIR}/include/${_dest_sub}" ) # process files foreach( _file IN LISTS _files ) if( NOT TARGET tqt-includes ) add_custom_target( tqt-includes WORKING_DIRECTORY "${CMAKE_BINARY_DIR}" COMMENT "Prepare includes..." ) endif() get_filename_component( _source_name "${_file}" NAME ) get_filename_component( _source_file "${_file}" ABSOLUTE ) file( RELATIVE_PATH _target_name "${CMAKE_SOURCE_DIR}" "${_source_file}" ) string( REPLACE "/" "+" _target_name "${_target_name}" ) file( RELATIVE_PATH _link_source "${CMAKE_BINARY_DIR}/include/${_dest_sub}" ${_source_file} ) file( RELATIVE_PATH _link_dest "${QT_INSTALL_HEADERS}" "${_dest}/${_source_name}" ) if( NOT TARGET ${_target_name} ) add_custom_command( OUTPUT ${CMAKE_BINARY_DIR}/include/${_link_dest} COMMAND ${CMAKE_COMMAND} -E create_symlink ${_link_source} ${CMAKE_BINARY_DIR}/include/${_link_dest} COMMENT "Include file ${_link_dest}" ) add_custom_target( ${_target_name} DEPENDS ${CMAKE_BINARY_DIR}/include/${_link_dest} ) add_dependencies( tqt-includes ${_target_name} ) endif() if( NOT "${_only_symlink}" ) install( FILES ${_file} DESTINATION ${_dest} ) endif() endforeach( _file ) endmacro( tqt_install_includes ) ################################################# ##### ##### tqt_header_for_source ##### ##### The macro search appropriate header files for the given list of sources and ##### append them to the list specified by _include_out ##### ##### Syntax: ##### tqt_header_for_source ( header_list source [source ...] ) macro( tqt_header_for_source _include_out ) foreach( _src ${ARGN} ) # As for now tqt has an "nt" prefix before filenames, so in order to handle all the casses # we will have to do some pattern matching get_filename_component( _src_path "${_src}" ABSOLUTE ) get_filename_component( _src_path "${_src_path}" PATH ) get_filename_component( _src_filename "${_src}" NAME_WE ) file( GLOB _header_candidates RELATIVE "${_src_path}/" "${_src_path}/*${_src_filename}*.h*" ) # filter out headers without TQ_OBJECT unset( _filtered_header_candidates ) foreach( _header IN LISTS _header_candidates ) if( NOT _header MATCHES "^(n?t)?${_src_filename}(_p)?\\.(h|hpp)$" ) continue() endif() file( STRINGS "${_src_path}/${_header}" _has_tq_object REGEX "T?Q_OBJECT" ) if( _has_tq_object ) list( APPEND _filtered_header_candidates "${_header}" ) endif( _has_tq_object ) endforeach( ) set( _header_candidates "${_filtered_header_candidates}" ) list( LENGTH _header_candidates _header_candidates_num ) if( ${_header_candidates_num} EQUAL 1 ) list( APPEND "${_include_out}" "${_src_path}/${_header_candidates}" ) elseif( "${_header_candidates_num}" GREATER 1 ) tde_message_fatal( "More than one candidates to automoc for ${_src_file}:" " ${_header_candidates}" ) else( ) # do nothing, skip the file endif( ) endforeach( _src ) endmacro( tqt_header_for_source ) ################################################# ##### ##### tqt_automoc ##### ##### The macro is used for 'moc' processing specifically for TQt as such ##### and adding them to an existing target. ##### ##### Syntax: ##### tqt_automoc( ##### [TARGET] target ##### [INCLUDES (AUTO|include_name) [include_name ...]] ##### ) macro( tqt_automoc ) unset( _target ) unset( _includes ) unset( _auto_includes ) set( _var _target ) foreach( _arg ${ARGN} ) # found directive "TARGET" if( "+${_arg}" STREQUAL "+TARGET" ) unset( _target ) set( _var _target ) set( _directive 1 ) endif( ) # found directive "INCLUDES" if( "+${_arg}" STREQUAL "+INCLUDES" ) unset( _includes ) set( _var _includes ) set( _directive 1 ) endif( ) # collect data if( _directive ) unset( _directive ) elseif( _var ) list( APPEND ${_var} ${_arg} ) endif( ) endforeach( ) # handle AUTO includes if( NOT _includes ) set( _auto_includes 1 ) elseif( AUTO IN_LIST _includes ) set( _auto_includes 1 ) list( REMOVE_ITEM _includes AUTO ) endif() # target must already exist if( NOT TARGET ${_target} ) tde_message_fatal( "The specified target does not exists." ) endif() # check tmoc executable if( NOT TMOC_EXECUTABLE ) tde_message_fatal( "tmoc is required but not found" ) endif() # get list of sources of specified target get_target_property( _sources "${_target}" SOURCES ) # automoc source files foreach( _src_file IN LISTS _sources ) get_filename_component( _src_file "${_src_file}" ABSOLUTE ) if( EXISTS "${_src_file}" ) # get some essential variables get_filename_component( _src_path "${_src_file}" ABSOLUTE ) get_filename_component( _src_path "${_src_path}" PATH ) get_filename_component( _src_filename "${_src_file}" NAME_WE ) file( RELATIVE_PATH _src_path_relative "${CMAKE_SOURCE_DIR}" "${_src_path}" ) # read source file and check if it has a moc include file( STRINGS "${_src_file}" _moc_includes REGEX "^#[ \t]*include[ \t]*[\"<]${_src_filename}\\.moc[\">]" ) # found included moc(s)? if( _moc_includes ) # file has a moc include; we should moc src file itself set( _moc_file_relative "${_src_path_relative}/${_src_filename}.moc" ) set( _moc_file "${CMAKE_BINARY_DIR}/${_moc_file_relative}" ) add_custom_command( OUTPUT "${_moc_file}" COMMAND "${TMOC_EXECUTABLE}" "${_src_file}" -o "${_moc_file}" COMMENT "Generating ${_moc_file_relative}" DEPENDS "${_src_file}" ) set_property( SOURCE "${_src_file}" APPEND PROPERTY OBJECT_DEPENDS "${_moc_file}" ) endif( ) endif( ) endforeach( _src_file ) # Get list of headers associated with sources if( _auto_includes ) tqt_header_for_source( _includes ${_sources} ) endif( ) # processing headers foreach( _inc IN LISTS _includes ) get_filename_component( _inc "${_inc}" ABSOLUTE ) get_filename_component( _inc_name "${_inc}" NAME_WE ) file( RELATIVE_PATH _inc_path_relative "${CMAKE_SOURCE_DIR}" "${_inc}" ) get_filename_component( _inc_path_relative "${_inc_path}" PATH ) set( _moc_file_relative "${_inc_path_relative}/moc_${_inc_name}.cpp" ) set( _moc_file "${CMAKE_CURRENT_BINARY_DIR}/${_moc_file_relative}" ) # moc-ing source add_custom_command( OUTPUT ${_moc_file} COMMAND "${TMOC_EXECUTABLE}" "${_inc}" -o "${_moc_file}" COMMENT "Generating ${_moc_file_relative}" DEPENDS "${_inc}" ) set_property( TARGET ${_target} APPEND PROPERTY SOURCES ${_moc_file} ) endforeach( _inc ) endmacro( tqt_automoc ) ################################################# ##### ##### tqt_create_translation ##### ##### The macro is used for create binary files for translations ##### ##### Syntax: ##### tqt_create_translation( ##### ) macro( tqt_create_translation ) file( GLOB _srcs RELATIVE ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_SOURCE_DIR}/*_*.ts ) list( SORT _srcs ) # generate *.qm files foreach( _src ${_srcs} ) get_filename_component( _src ${_src} ABSOLUTE ) get_filename_component( _out ${_src} NAME_WE ) string( REPLACE "@" "_" _target ${_out} ) set( _out_filename "${_out}.qm" ) set( _install_filename "${_out}.qm" ) add_custom_command( OUTPUT ${_out_filename} COMMAND tqlrelease ${_src} -qm ${_out_filename} COMMENT "Build translation ${_out}" DEPENDS ${_src} ) add_custom_target( "${_target}-translation" ALL DEPENDS ${_out_filename} ) install( FILES ${CMAKE_CURRENT_BINARY_DIR}/${_out_filename} RENAME ${_install_filename} DESTINATION ${QT_INSTALL_TRANSLATIONS} ) endforeach( ) endmacro( tqt_create_translation )