diff --git a/etc/cmake/latest/GuiCommands.cmake b/etc/cmake/latest/GuiCommands.cmake index fa7e929d491345814b045045a03176ffde3babf8..7ec6ae199caa20636ff8345e4fa0638656648da7 100644 --- a/etc/cmake/latest/GuiCommands.cmake +++ b/etc/cmake/latest/GuiCommands.cmake @@ -21,57 +21,80 @@ string(REGEX REPLACE "/[^/]+$" "" QT_EXECUTABLE_PRE "${QT_MOC_EXECUTABLE}") function(armarx_add_qt_plugin TARGET) # Parse arguments. - set(single_param) - set(flag_param) - set(multi_param PLUGIN_SOURCES PLUGIN_HEADERS SOURCES HEADERS UI_FILES RESOURCE_FILES - DEPENDENCIES DEPENDENCIES_LEGACY WIDGET_CONTROLLERS) + set(single_param WIDGET_CONTROLLER) + set(flag_param MANUAL_QT_PLUGIN_SOURCES) + set(multi_param SOURCES HEADERS UI_FILES RESOURCE_FILES DEPENDENCIES DEPENDENCIES_LEGACY) cmake_parse_arguments(PARSE_ARGV 1 AX "${flag_param}" "${single_param}" "${multi_param}") if(DEFINED AX_UNPARSED_ARGUMENTS) message(FATAL_ERROR "${TARGET}: Unknown arguments `${AX_UNPARSED_ARGUMENTS}`.") endif() - if(NOT AX_WIDGET_CONTROLLER) - message(FATAL_ERROR "${TARGET}: Plugins must have at least one WIDGET_CONTROLLER.") - endif() - - # Auto-generate plugin headers and sources if requested. - if(${AX_PLUGIN}) - # GUI plugin name. - # Make sure to remove only the last 'GuiPlugin' otherwise you cannot name your plugins '*GuiPlugin' - string(REGEX REPLACE "GuiPlugin$" "" ARMARX_GUI_PLUGIN_PREFIX "${ARMARX_TARGET_NAME}") + # Variables modified within this scope. + set(SOURCES "${AX_SOURCES}") + set(HEADERS "${AX_HEADERS}") + + # Auto-generate plugin headers and sources if requested. If not (i.e., if + # AX_MANUAL_QT_PLUGIN_SOURCES is set, this function is not different to + # `armarx_add_qt_library`, except that the intention of the user is clearer. + if(NOT ${AX_MANUAL_QT_PLUGIN_SOURCES}) + if(NOT AX_WIDGET_CONTROLLER) + message(FATAL_ERROR "${TARGET}: Qt plugins must have a registered widget controller in WIDGET_CONTROLLER to generate Qt plugin source files. You can also provide custom sources in SOURCES and HEADERS and enable MANUAL_QT_PLUGIN_SOURCES.") + endif() - # Get relative path for subdir. - file(RELATIVE_PATH subdir "${PROJECT_SOURCECODE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}") + # Extract controller name from namespace(s). + string(REPLACE "::" ";" WIDGET_CONTROLLER_NS_LIST "${AX_WIDGET_CONTROLLER}") + list(POP_BACK WIDGET_CONTROLLER_NS_LIST WIDGET_CONTROLLER_NAME) + string(REPLACE ";" "::" WIDGET_CONTROLLER_NS "${WIDGET_CONTROLLER_NS_LIST}") # Get the widget controller header. - set(tmp_headers ${HEADERS}) - set(tmp_regex "(^|\\.*/)${ARMARX_GUI_PLUGIN_PREFIX}WidgetController\\.h") - list(FILTER tmp_headers INCLUDE REGEX "${tmp_regex}") - list(REMOVE_DUPLICATES tmp_headers) - list(LENGTH tmp_headers tmp_headers_len) - if(NOT "${tmp_headers_len}" STREQUAL "1") - message(FATAL_ERROR "Failed to auto generate the GuiPlugin sources. Cannot find the widget controller `${tmp_regex}`.") + set(HEADERS_CP ${HEADERS}) + set(HEADERS_FILTER_REGEX "(^|\\.*/)${WIDGET_CONTROLLER_NAME}\\.h") + list(FILTER HEADERS_CP INCLUDE REGEX "${HEADERS_FILTER_REGEX}") + list(REMOVE_DUPLICATES HEADERS_CP) + list(LENGTH HEADERS_CP HEADERS_CP_LEN) + if(${HEADERS_CP_LEN} EQUAL 0) + message(FATAL_ERROR "${TARGET}: Failed to auto generate the Qt plugin sources. Cannot find header `${WIDGET_CONTROLLER_NAME}.h` of WIDGET_CONTROLLER `${AX_WIDGET_CONTROLLER}` in supplied HEADERS.") endif() - list(GET tmp_headers 0 tmp_hdr) - set(ARMARX_GUI_PLUGIN_WIDGET_CONTROLLER_HEDER "${subdir}/${tmp_hdr}") + list(GET HEADERS_CP 0 WIDGET_CONTROLLER_HEADER_INCLUDE) + + # Get relative path for the include. + file(RELATIVE_PATH INCLUDE_PATH "${PROJECT_SOURCECODE_DIR}" "${CMAKE_CURRENT_SOURCE_DIR}") + + # Variables for template configuration. + set(QT_PLUGIN_NAMESPACE "${WIDGET_CONTROLLER_NS}") + set(QT_WIDGET_CONTROLLER_INCLUDE "${INCLUDE_PATH}/${WIDGET_CONTROLLER_HEADER_INCLUDE}") + set(QT_WIDGET_CONTROLLER_FQ_NAME "${AX_WIDGET_CONTROLLER}") + + # Generate Qt plugin files. + set(OUT_FILE "${CMAKE_CURRENT_BINARY_DIR}/QtPlugin") + foreach(EXT h cpp) + set(QT_PLUGIN_SOURCE_FILE "${ArmarXGui_TEMPLATES_DIR}/qt_plugin/QtPlugin.in.${EXT}") - # Generate and add files. - set(outfile "${GENERATE_BASE_DIR}/${subdir}/${ARMARX_TARGET_NAME}") - foreach(suff h cpp) - # TODO: Move template to ArmarXGui configure_file( - "${ArmarXCore_TEMPLATES_DIR}/GuiPluginTemplate/GuiPlugin.tmp.${suff}" - "${outfile}.${suff}" + "${QT_PLUGIN_SOURCE_FILE}" + "${OUT_FILE}.${EXT}" + USE_SOURCE_PERMISSIONS @ONLY ) endforeach() - list(APPEND SOURCES "${outfile}.cpp") - list(APPEND HEADERS "${outfile}.h") + # Add generated files to SOURCES and HEADERS. + list(APPEND SOURCES "${OUT_FILE}.cpp") + list(APPEND HEADERS "${OUT_FILE}.h") + else() + if(AX_WIDGET_CONTROLLER) + message(WARNING "${TARGET}: Not generating sources for WIDGET_CONTROLLER `${AX_WIDGET_CONTROLLERS}` (MANUAL_QT_PLUGIN_SOURCES set, assuming user provided custom sources). You may remove WIDGET_CONTROLLER to get rid of this warning.") + endif() endif() + # Define the actual library with auto-generated files appended. armarx_add_qt_library(${TARGET} - + SOURCES ${SOURCES} + HEADERS ${HEADERS} + UI_FILES ${AX_UI_FILES} + RESOURCE_FILES ${AX_RESOURCE_FILES} + DEPENDENCIES ${AX_DEPENDENCIES} + DEPENDENCIES_LEGACY ${AX_DEPENDENCIES_LEGACY} ) endfunction() @@ -80,8 +103,7 @@ function(armarx_add_qt_library TARGET) # Parse arguments. set(single_param) set(flag_param PLUGIN) - set(multi_param PLUGIN_SOURCES PLUGIN_HEADERS SOURCES HEADERS UI_FILES RESOURCE_FILES - DEPENDENCIES DEPENDENCIES_LEGACY) + set(multi_param SOURCES HEADERS UI_FILES RESOURCE_FILES DEPENDENCIES DEPENDENCIES_LEGACY) cmake_parse_arguments(PARSE_ARGV 1 AX "${flag_param}" "${single_param}" "${multi_param}") if(DEFINED AX_UNPARSED_ARGUMENTS) message(FATAL_ERROR "${TARGET}: Unknown arguments `${AX_UNPARSED_ARGUMENTS}`.")