set(_QT_VERSIONS_ 4 5) foreach(_v ${_QT_VERSIONS_}) if (NOT DEFINED TARGET_SUFFIX_Qt${_v}) set(TARGET_SUFFIX_Qt${_v} "${_v}") set(MULTILIB_SUFFIX_Qt${_v} "${_v}") endif() set(MOC_INC_Qt${_v}) endforeach() if (NOT DEFINED QT_MULTILIB_LIST) set(QT_MULTILIB_LIST) endif() #set(TARGET_SUFFIX_Qt4 "") # usage: find_qt([ ...] [Qt4] [Qt5]) # find Qt4 or/and Qt5 packages # if Qt4/5 found, set # * Qt<4/5>_BIN var to Qt binary dir # * Qt<4/5>_PLUGINS_DIR var to Qt plugins dir macro(find_qt) set(_QCOMP) foreach(_v ${_QT_VERSIONS_}) set(_NEED${_v} 0) set(LOCAL_FOUND${_v} 0) set(MOC_INC_Qt${_v}) set(Qt${_v}_INCLUDES) set(Qt${_v}_LIBRARIES) set(Qt${_v}_BIN) set(Qt${_v}_PLUGINS_DIR) set(Qt${_v}_LANG_DIR) endforeach() set(_NEED_SOME 0) set(_QUIET) foreach(_i ${ARGN}) set(_FOUND_NEED 0) foreach(_v ${_QT_VERSIONS_}) if ("x${_i}" STREQUAL "xQt${_v}") set(_NEED${_v} 1) set(_NEED_SOME 1) set(_FOUND_NEED 1) endif() if ("x${_i}" STREQUAL "xQUIET") set(_QUIET QUIET) endif() endforeach() if (NOT _FOUND_NEED) list(APPEND _QCOMP "${_i}") endif() endforeach() if (NOT _NEED_SOME) foreach(_v ${_QT_VERSIONS_}) set(_NEED${_v} 1) endforeach() endif() list(REMOVE_DUPLICATES _QCOMP) if (_NEED4) find_package(Qt4 ${_QUIET}) if (Qt4_FOUND) set(LOCAL_FOUND4 1) get_filename_component(Qt4_BIN ${QT_QMAKE_EXECUTABLE} PATH) set(Qt4_INCLUDES ${QT_INCLUDES}) foreach(m ${_QCOMP}) string(TOUPPER "${m}" _um) #message("${QT_QT${_um}_FOUND}") if (${QT_QT${_um}_FOUND}) list(APPEND Qt4_LIBRARIES ${QT_QT${_um}_LIBRARY}) endif() endforeach() set(Qt4_PLUGINS_DIR ${QT_PLUGINS_DIR}) set(Qt4_LANG_DIR ${Qt4_BIN}/../translations) endif() endif() if (_NEED5) #set(_MSG 1) #if (Qt5_FOUND) # set(_MSG 0) #endif() find_package(Qt5 COMPONENTS LinguistTools UiPlugin Widgets ${_QCOMP} ${_QUIET}) if (Qt5_FOUND) set(LOCAL_FOUND5 1) set(_Qt5Modules) foreach(m ${_QCOMP}) if (${Qt5${m}_FOUND}) list(APPEND _Qt5Modules ${m}) list(APPEND Qt5_INCLUDES ${Qt5${m}_INCLUDE_DIRS}) list(APPEND Qt5_LIBRARIES ${Qt5${m}_LIBRARIES}) endif() endforeach() #get_property(_up_dir TARGET Qt5::UiPlugin PROPERTY INTERFACE_INCLUDE_DIRECTORIES) #message("${_up_dir}") #if (NOT "x${_up_dir}" STREQUAL "x") # list(APPEND Qt5_INCLUDES ${_up_dir}) #endif() get_target_property(_Qt5_qmake Qt5::qmake LOCATION) get_filename_component(Qt5_BIN ${_Qt5_qmake} PATH) foreach(_p ${Qt5Gui_PLUGINS}) get_target_property(_l ${_p} LOCATION) get_filename_component(_l ${_l} DIRECTORY) string(FIND "${_l}" "/" _ind REVERSE) string(SUBSTRING "${_l}" 0 ${_ind} _l) set(Qt5_PLUGINS_DIR ${_l}) #message("Qt5: plugins dir: ${Qt5_PLUGINS_DIR}") break() endforeach() string(FIND "${Qt5_BIN}" "/" _ind REVERSE) string(SUBSTRING "${Qt5_BIN}" 0 ${_ind} _qt5_root) if ("x${Qt5_PLUGINS_DIR}" STREQUAL "x") set(Qt5_PLUGINS_DIR "${_qt5_root}/plugins") endif() if (APPLE) list(APPEND MOC_INC_Qt5 "-F${_qt5_root}/lib") endif() set(Qt5_LANG_DIR ${Qt5_BIN}/../translations) if (NOT _QT5_MSG) message(STATUS "Found Qt5: ${_Qt5_qmake} (found version \"${Qt5_VERSION}\")") set(_QT5_MSG 1 CACHE BOOL "msg_qt5" FORCE) #message(STATUS "Found Qt5 modules: ${_Qt5Modules}") endif() endif() endif() # set() foreach(_v ${_QT_VERSIONS_}) if (LOCAL_FOUND${_v}) foreach(_p ${Qt${_v}_INCLUDES}) list(APPEND MOC_INC_Qt${_v} "-I${_p}") #message("${_p}") endforeach() endif() #message("${MOC_INC_Qt${_v}}") endforeach() endmacro() # usage: qt_sources( [NO_DEFAULT] [DIR ] [ ...]) # collect all sources, optionally in directory and # additional filters . By default filter files with regexps # "*.h", "*.hpp", "*.c", "*.cpp", "*.ui", "*.qrc", "*.rc", "*.ts" and "lang/*.ts". # Default filters disabled with option NO_DEFAULT macro(qt_sources OUT) set(${OUT}) set(_DIR "") set(_IS_DIR 0) set(_NO_DEFAULT 0) set(_DEFAULT) set(_REGEXP) set(_REGEXP_WD) foreach(_i ${ARGN}) if (_IS_DIR) set(_DIR "${_i}") set(_IS_DIR 0) else() if ("x${_i}" STREQUAL "xDIR") set(_IS_DIR 1) else() if ("x${_i}" STREQUAL "xNO_DEFAULT") set(_NO_DEFAULT 1) else() list(APPEND _REGEXP ${_i}) endif() endif() endif() endforeach() if (NOT "x${_DIR}" STREQUAL "x") #file(TO_CMAKE_PATH "${_DIR}//" _DIR) string(REPLACE "\\" "/" _DIR "${_DIR}/") string(REPLACE "//" "/" _DIR "${_DIR}") endif() foreach(_i ${_REGEXP}) list(APPEND _REGEXP_WD "${_DIR}${_i}") endforeach() if (NOT _NO_DEFAULT) set(_DEFAULT "${_DIR}*.h" "${_DIR}*.hpp" "${_DIR}*.c" "${_DIR}*.cpp" "${_DIR}*.ui" "${_DIR}*.qrc" "${_DIR}*.rc" "${_DIR}*.ts" "${_DIR}lang/*.ts") endif() #message("${_DEFAULT}, ${_REGEXP_WD}") file(GLOB ${OUT} ${_DEFAULT} ${_REGEXP_WD}) endmacro() # usage: qt_wrap( ... [HDRS ] [CPPS ] [QMS ]) # prepare sources for compile # store headers to , all wrapped Qt4 files to _Qt4 and Qt5 files to _Qt5 # version are automatic detected after find_qt() call macro(qt_wrap) set(HDR_VAR) set(CPP_VAR) set(QM_VAR) set(_HDR_ARG 0) set(_CPP_ARG 0) set(_QM_ARG 0) set(WAS_HDR_ARG 0) set(WAS_CPP_ARG 0) set(WAS_QM_ARG 0) set(FILE_LIST) foreach(_i ${ARGN}) if (_HDR_ARG) set(HDR_VAR ${_i}) set(WAS_HDR_ARG 1) set(_HDR_ARG 0) else() if (_CPP_ARG) set(CPP_VAR ${_i}) set(WAS_CPP_ARG 1) set(_CPP_ARG 0) else() if (_QM_ARG) set(QM_VAR ${_i}) set(WAS_QM_ARG 1) set(_QM_ARG 0) else() if ("x${_i}" STREQUAL "xHDRS") set(_HDR_ARG 1) else() if ("x${_i}" STREQUAL "xCPPS") set(_CPP_ARG 1) else() if ("x${_i}" STREQUAL "xQMS") set(_QM_ARG 1) else() list(APPEND FILE_LIST "${_i}") endif() endif() endif() endif() endif() endif() endforeach() foreach(_v ${_QT_VERSIONS_}) set(CPP${_v}_VAR) set(QM${_v}_VAR) if (LOCAL_FOUND${_v}) if (WAS_CPP_ARG) set(CPP${_v}_VAR ${CPP_VAR}_Qt${_v}) endif() if (WAS_QM_ARG) set(QM${_v}_VAR ${QM_VAR}_Qt${_v}) endif() endif() endforeach() #message("found 4: ${LOCAL_FOUND4}, 5: ${LOCAL_FOUND5}") #message("has HRDS: ${WAS_HDR_ARG}: ${HDR_VAR}") #message("has CPPS4: ${WAS_CPP_ARG}: ${CPP4_VAR}") #message("has CPPS5: ${WAS_CPP_ARG}: ${CPP5_VAR}") #message("files: ${FILE_LIST}") set(H_LIST) set(CPP_LIST) set(UI_LIST) set(RES_LIST) set(RC_LIST) set(TS_LIST) foreach(_i ${FILE_LIST}) get_filename_component(_EXT "${_i}" EXT) #message("${_EXT}") if (NOT ("x${_EXT}" STREQUAL "x")) if (("x${_EXT}" STREQUAL "x.h") OR ("x${_EXT}" STREQUAL "x.hpp")) list(APPEND H_LIST "${_i}") #message("header") endif() if (("x${_EXT}" STREQUAL "x.c") OR ("x${_EXT}" STREQUAL "x.cpp") OR ("x${_EXT}" STREQUAL "x.cxx")) list(APPEND CPP_LIST "${_i}") #message("source") endif() if ("x${_EXT}" STREQUAL "x.ui") list(APPEND UI_LIST "${_i}") endif() if ("x${_EXT}" STREQUAL "x.qrc") list(APPEND RES_LIST "${_i}") endif() if ("x${_EXT}" STREQUAL "x.rc") list(APPEND RC_LIST "${_i}") endif() if ("x${_EXT}" STREQUAL "x.ts") list(APPEND TS_LIST "${_i}") endif() endif() endforeach() if (WAS_HDR_ARG) set(${HDR_VAR}) list(APPEND ${HDR_VAR} ${H_LIST}) endif() set(SRC_CMAKE_CURRENT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) foreach(_v ${_QT_VERSIONS_}) if (LOCAL_FOUND${_v} AND WAS_CPP_ARG) set(CMAKE_CURRENT_BINARY_DIR ${SRC_CMAKE_CURRENT_BINARY_DIR}/qt${_v}) set(${CPP${_v}_VAR}) if (WAS_QM_ARG) set(${QM${_v}_VAR}) endif() set(MOCS${_v}) set(CUIS${_v}) set(CRES${_v}) if (${_v} EQUAL 4) qt4_wrap_cpp(MOCS${_v} ${H_LIST} OPTIONS -nw ${MOC_INC_Qt4}) qt4_wrap_ui(CUIS${_v} ${UI_LIST}) qt4_add_resources(CRES${_v} ${RES_LIST}) if (WAS_QM_ARG) set(${QM${_v}_VAR} "") qt4_add_translation(${QM${_v}_VAR} ${TS_LIST}) endif() else() if (${_v} EQUAL 5) qt5_wrap_cpp(MOCS${_v} ${H_LIST} OPTIONS -nw ${MOC_INC_Qt5}) qt5_wrap_ui(CUIS${_v} ${UI_LIST}) qt5_add_resources(CRES${_v} ${RES_LIST}) if (WAS_QM_ARG) set(${QM${_v}_VAR} "") qt5_add_translation(${QM${_v}_VAR} ${TS_LIST}) endif() else() endif() endif() #message("${${QM${_v}_VAR}}") list(APPEND ${CPP${_v}_VAR} ${CPP_LIST}) list(APPEND ${CPP${_v}_VAR} ${RC_LIST}) list(APPEND ${CPP${_v}_VAR} ${MOCS${_v}}) list(APPEND ${CPP${_v}_VAR} ${CUIS${_v}}) list(APPEND ${CPP${_v}_VAR} ${CRES${_v}}) if (WAS_QM_ARG) list(APPEND ${CPP${_v}_VAR} ${${QM${_v}_VAR}}) endif() #message("${${QM${_v}_VAR}}") endif() endforeach() set(CMAKE_CURRENT_BINARY_DIR ${SRC_CMAKE_CURRENT_BINARY_DIR}) endmacro() macro(_qt_split_add_args _P _A) set(${_P}) set(${_A}) foreach(_i ${ARGN}) if (NOT ("x${${_i}_Qt${_v}}" STREQUAL "x")) list(APPEND ${_A} ${${_i}_Qt${_v}}) else() if (("x${_i}" STREQUAL "xWIN32") OR ("x${_i}" STREQUAL "xMACOSX_BUNDLE") OR ("x${_i}" STREQUAL "xSTATIC") OR ("x${_i}" STREQUAL "xSHARED") OR ("x${_i}" STREQUAL "xMODULE") OR ("x${_i}" STREQUAL "xEXCLUDE_FROM_ALL")) list(APPEND ${_P} ${_i}) else() if ("x${${_i}}" STREQUAL "x") list(APPEND ${_A} ${_i}) else() list(APPEND ${_A} ${${_i}}) endif() endif() endif() endforeach() endmacro() # usage: qt_add_executable( [WIN32] [MACOSX_BUNDLE] [EXCLUDE_FROM_ALL] source1 [source2 ...]) # add executables for founded Qt versions, target names is # all needed Qt includes automatic added to corresponding targets # cant be CPPS variable passed to qt_wrap() or some list or filename macro(qt_add_executable _NAME) foreach(_v ${_QT_VERSIONS_}) if (LOCAL_FOUND${_v}) _qt_split_add_args(_PREF _ARGS ${ARGN}) #message("${_PREF}") #message("${_ARGS}") set(_TARGET ${_NAME}${TARGET_SUFFIX_Qt${_v}}) add_executable(${_TARGET} ${_PREF} ${_ARGS}) set(_${_NAME}_is_qt 1) target_include_directories(${_TARGET} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/qt${_v} ${Qt${_v}_INCLUDES}) ### add_definitions(${Qt5Widgets_DEFINITIONS}) ### target_compile_definitions(${_TARGET} PUBLIC ${CMAKE_CURRENT_BINARY_DIR}/qt${_v} ${Qt${_v}_INCLUDES}) #message("add exe: \"${_TARGET}\", \"${_PREF}\"") endif() endforeach() endmacro() # usage: qt_add_library( [STATIC | SHARED | MODULE] [EXCLUDE_FROM_ALL] source1 [source2 ...]) # add library for founded Qt versions, target names is # all needed Qt includes automatic added to corresponding targets # cant be CPPS variable passed to qt_wrap() or some list or filename macro(qt_add_library _NAME) foreach(_v ${_QT_VERSIONS_}) if (LOCAL_FOUND${_v}) _qt_split_add_args(_PREF _ARGS ${ARGN}) #message("${_PREF}") #message("${_ARGS}") set(_TARGET ${_NAME}${TARGET_SUFFIX_Qt${_v}}) add_library(${_TARGET} ${_PREF} ${_ARGS}) set(_${_NAME}_is_qt 1) target_include_directories(${_TARGET} PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} ${CMAKE_CURRENT_BINARY_DIR} ${CMAKE_CURRENT_BINARY_DIR}/qt${_v} ${Qt${_v}_INCLUDES}) #message("add lib: \"${_TARGET}\"") endif() endforeach() endmacro() macro(_qt_multitarget_suffix_ _OUT _IN _v) if (NOT "x${MULTILIB_${_IN}_SUFFIX_Qt${_v}}" STREQUAL "x") set(${_OUT} "${MULTILIB_${_IN}_SUFFIX_Qt${_v}}") else() set(${_OUT} "${MULTILIB_SUFFIX_Qt${_v}}") endif() endmacro() # usage: qt_target_link_libraries( ... ...) # link targets for founded Qt versions, target names is # all needed Qt libraries automatic added to corresponding targets # if QT_MULTILIB_LIST contains some linking library, to it name automatic # add or individual libname<_SUFFIX_Qt?> macro(qt_target_link_libraries _NAME) foreach(_v ${_QT_VERSIONS_}) if (LOCAL_FOUND${_v}) set(_TARGET ${_NAME}${TARGET_SUFFIX_Qt${_v}}) set(_ARGS) foreach(_i ${ARGN}) set(_ind -1) list(FIND QT_MULTILIB_LIST "${_i}" _ind) if (_ind GREATER -1) _qt_multitarget_suffix_(_TS ${_i} ${_v}) list(APPEND _ARGS ${_i}${_TS}) else() list(APPEND _ARGS ${_i}) endif() endforeach() target_link_libraries(${_TARGET} ${Qt${_v}_LIBRARIES} ${_ARGS}) #message("link ${_TARGET}: ${Qt${_v}_LIBRARIES} ${_ARGS}") endif() endforeach() endmacro() # usage: qt_target_compile_definitions(...), syntax similar to original "target_compile_definitions()" # Specify compile definitions to use when compiling a given macro(qt_target_compile_definitions _NAME) foreach(_v ${_QT_VERSIONS_}) if (LOCAL_FOUND${_v}) set(_TARGET ${_NAME}${TARGET_SUFFIX_Qt${_v}}) target_compile_definitions(${_TARGET} ${ARGN}) endif() endforeach() endmacro() # usage: qt_install(...), syntax similar to original "install()" # install targets for founded Qt versions # if DESTINATION set to "QtBin" files will be installed # to corresponding Qt binary directory # if DESTINATION set to "QtLang" files will be installed # to corresponding Qt translation directory # if DESTINATION starts with "QtPlugins" files will be installed # to corresponding Qt plugins directory macro(qt_install) set(_prev_inst) #message("command: ${ARGN}") foreach(_v ${_QT_VERSIONS_}) if (LOCAL_FOUND${_v}) set(_INST_LIST) set(_IS_TARGET 0) set(_IS_FILES 0) set(_IS_DEST 0) set(_IS_LANG 0) set(_INVALID 0) foreach(_i ${ARGN}) if ("x${_i}" STREQUAL "xQtLang") set(_IS_LANG 1) endif() endforeach() foreach(_i ${ARGN}) if (_IS_TARGET) set(_IS_TARGET 0) if (_${_i}_is_qt) set(_INST_LIST ${_INST_LIST} ${_i}${TARGET_SUFFIX_Qt${_v}}) else() set(_INST_LIST ${_INST_LIST} ${_i}) endif() else() if (_IS_FILES) set(_IS_FILES 0) if (_IS_LANG) if (("x${${_i}_Qt${_v}}" STREQUAL "x") OR ("x${_i}" STREQUAL "xDESTINATION")) #return() set(_INVALID 1) else() set(_INST_LIST ${_INST_LIST} ${${_i}_Qt${_v}}) endif() else() set(_INST_LIST ${_INST_LIST} ${_i}) endif() else() if (_IS_DEST) set(_IS_DEST 0) if ("x${_i}" STREQUAL "xQtBin") set(_INST_LIST ${_INST_LIST} "${Qt${_v}_BIN}") else() if ("x${_i}" STREQUAL "xQtLang") set(_INST_LIST ${_INST_LIST} "${Qt${_v}_LANG_DIR}") else() set(_ind -1) string(FIND "${_i}" "QtPlugins" _ind) if (_ind GREATER -1) string(REPLACE "QtPlugins" "${Qt${_v}_PLUGINS_DIR}" _o "${_i}") set(_INST_LIST ${_INST_LIST} "${_o}") else() set(_INST_LIST ${_INST_LIST} ${_i}) endif() endif() endif() else() set(_INST_LIST ${_INST_LIST} ${_i}) if ("x${_i}" STREQUAL "xTARGETS") set(_IS_TARGET 1) else() if ("x${_i}" STREQUAL "xFILES") set(_IS_FILES 1) else() if ("x${_i}" STREQUAL "xDESTINATION") set(_IS_DEST 1) endif() endif() endif() endif() endif() endif() endforeach() if (NOT _INVALID) if (NOT ("x${_prev_inst}" STREQUAL "x${_INST_LIST}")) #message("install: ${_INST_LIST}") install(${_INST_LIST}) set(_prev_inst "${_INST_LIST}") endif() endif() endif() endforeach() endmacro()