diff --git a/CMakeLists.txt b/CMakeLists.txt index a6a85c3..64734f1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -77,6 +77,7 @@ set(CMAKE_MODULE_FILES cmake/modules/LibraryTarget.cmake cmake/modules/TestUtilities.cmake cmake/modules/TestTarget.cmake + cmake/modules/AppUtilities.cmake cmake/modules/AppTarget.cmake cmake/modules/WindowsResources.cmake cmake/modules/TemplateFinder.cmake diff --git a/cmake/modules/AppTarget.cmake b/cmake/modules/AppTarget.cmake index de1678f..13e76c1 100644 --- a/cmake/modules/AppTarget.cmake +++ b/cmake/modules/AppTarget.cmake @@ -180,108 +180,6 @@ if (NOT META_NO_INSTALL_TARGETS AND ENABLE_INSTALL_TARGETS) endif () endif () -# find template for *.desktop and AppStream files -include(TemplateFinder) -find_template_file("desktop" CPP_UTILITIES APP_DESKTOP_TEMPLATE_FILE) -find_template_file("appdata.xml" CPP_UTILITIES APP_APPSTREAM_TEMPLATE_FILE) - -# define generic function to add *.desktop files -include(CMakeParseArguments) -function (add_custom_desktop_file) - # skip if not building with GUI support - if (NOT META_DESKTOP_FILE_FOR_CLI AND ((NOT DEFINED META_GUI_OPTIONAL OR META_GUI_OPTIONAL) AND NOT (WIDGETS_GUI - OR QUICK_GUI))) - return() - endif () - - # parse arguments - set(ONE_VALUE_ARGS - FILE_NAME - DESKTOP_FILE_APP_NAME - DESKTOP_FILE_GENERIC_NAME - DESKTOP_FILE_DESCRIPTION - DESKTOP_FILE_CATEGORIES - DESKTOP_FILE_CMD - DESKTOP_FILE_ICON - DESKTOP_FILE_ADDITIONAL_ENTRIES) - set(MULTI_VALUE_ARGS) - set(OPTIONAL_ARGS) - cmake_parse_arguments(ARGS "${OPTIONAL_ARGS}" "${ONE_VALUE_ARGS}" "${MULTI_VALUE_ARGS}" ${ARGN}) - if (NOT ARGS_FILE_NAME - OR NOT ARGS_DESKTOP_FILE_APP_NAME - OR NOT ARGS_DESKTOP_FILE_CMD) - message(FATAL_ERROR "Not all mandatory arguments specified.") - endif () - if (NOT ARGS_DESKTOP_FILE_GENERIC_NAME) - set(ARGS_DESKTOP_FILE_GENERIC_NAME "${ARGS_DESKTOP_FILE_APP_NAME}") - endif () - - # create desktop file from template - configure_file("${APP_DESKTOP_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/resources/${ARGS_FILE_NAME}.desktop") - # add install for the desktop file - install( - FILES "${CMAKE_CURRENT_BINARY_DIR}/resources/${ARGS_FILE_NAME}.desktop" - DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications" - COMPONENT desktop) -endfunction () - -# define function to add *.desktop file and meta info from project meta data -function (add_desktop_file) - # skip if not building with GUI support - if (NOT META_DESKTOP_FILE_FOR_CLI AND ((NOT DEFINED META_GUI_OPTIONAL OR META_GUI_OPTIONAL) AND NOT (WIDGETS_GUI - OR QUICK_GUI))) - return() - endif () - - # compose actions - set(DESKTOP_FILE_ADDITIONAL_ENTRIES "") - foreach (ACTION_VAR ${META_APP_ACTIONS}) - list(GET META_APP_ACTION_${ACTION_VAR} 0 ACTION_ID) - list(GET META_APP_ACTION_${ACTION_VAR} 1 ACTION_NAME) - list(GET META_APP_ACTION_${ACTION_VAR} 2 ACTION_ARGS) - set(DESKTOP_FILE_ADDITIONAL_ENTRIES - "${DESKTOP_FILE_ADDITIONAL_ENTRIES}\n[Desktop Action ${ACTION_ID}]\nName=${ACTION_NAME}\nExec=${META_TARGET_NAME} ${ACTION_ARGS}" - ) - endforeach () - - # create desktop file - add_custom_desktop_file( - FILE_NAME - "${META_ID}" - DESKTOP_FILE_APP_NAME - "${META_APP_NAME}" - DESKTOP_FILE_GENERIC_NAME - "${META_GENERIC_NAME}" - DESKTOP_FILE_DESCRIPTION - "${META_APP_DESCRIPTION}" - DESKTOP_FILE_CATEGORIES - "${META_APP_CATEGORIES}" - DESKTOP_FILE_CMD - "${META_TARGET_NAME}" - DESKTOP_FILE_ICON - "${NAMESPACE_PREFIX}${META_PROJECT_NAME}${META_CONFIG_SUFFIX}" - DESKTOP_FILE_ADDITIONAL_ENTRIES - "${DESKTOP_FILE_ADDITIONAL_ENTRIES}") - - # read body for appstream desktop file from resources - set(META_APP_APPDATA_BODY_FILE "${CMAKE_CURRENT_SOURCE_DIR}/resources/body.appdata.xml") - set(META_APP_APPDATA_SUBSTITUTED_BODY_FILE "${CMAKE_CURRENT_BINARY_DIR}/resources/${META_ID}.body.appdata.xml") - if (EXISTS "${META_APP_APPDATA_BODY_FILE}") - configure_file("${META_APP_APPDATA_BODY_FILE}" "${META_APP_APPDATA_SUBSTITUTED_BODY_FILE}" @ONLY) - file(READ "${META_APP_APPDATA_SUBSTITUTED_BODY_FILE}" META_APP_APPDATA_BODY) - # add indentation of two additional spaces - string(REGEX REPLACE "\n([^$])" "\n \\1" META_APP_APPDATA_BODY "${META_APP_APPDATA_BODY}") - endif () - - # create appstream desktop file from template - set(APPSTREAM_FILE "${CMAKE_CURRENT_BINARY_DIR}/resources/${META_ID}.appdata.xml") - configure_file("${APP_APPSTREAM_TEMPLATE_FILE}" "${APPSTREAM_FILE}" @ONLY) - - # add install for the appstream file - install( - FILES "${APPSTREAM_FILE}" - DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo" - COMPONENT appimage) -endfunction () +include(AppUtilities) set(TARGET_CONFIG_DONE YES) diff --git a/cmake/modules/AppUtilities.cmake b/cmake/modules/AppUtilities.cmake new file mode 100644 index 0000000..3077f98 --- /dev/null +++ b/cmake/modules/AppUtilities.cmake @@ -0,0 +1,116 @@ +cmake_minimum_required(VERSION 3.3.0 FATAL_ERROR) + +# prevent multiple inclusion +if (DEFINED APPLICATION_UTILITIES_LOADED) + return() +endif () +set(APPLICATION_UTILITIES_LOADED YES) + +# find template for *.desktop and AppStream files +include(TemplateFinder) +find_template_file("desktop" CPP_UTILITIES APP_DESKTOP_TEMPLATE_FILE) +find_template_file("appdata.xml" CPP_UTILITIES APP_APPSTREAM_TEMPLATE_FILE) + +# define generic function to add *.desktop files +include(CMakeParseArguments) +function (add_custom_desktop_file) + # skip if not building with GUI support + if (NOT META_DESKTOP_FILE_FOR_CLI AND ((NOT DEFINED META_GUI_OPTIONAL OR META_GUI_OPTIONAL) AND NOT (WIDGETS_GUI + OR QUICK_GUI))) + return() + endif () + + # parse arguments + set(ONE_VALUE_ARGS + FILE_NAME + DESKTOP_FILE_APP_NAME + DESKTOP_FILE_GENERIC_NAME + DESKTOP_FILE_DESCRIPTION + DESKTOP_FILE_CATEGORIES + DESKTOP_FILE_CMD + DESKTOP_FILE_ICON + DESKTOP_FILE_ADDITIONAL_ENTRIES) + set(MULTI_VALUE_ARGS) + set(OPTIONAL_ARGS) + cmake_parse_arguments(ARGS "${OPTIONAL_ARGS}" "${ONE_VALUE_ARGS}" "${MULTI_VALUE_ARGS}" ${ARGN}) + if (NOT ARGS_FILE_NAME + OR NOT ARGS_DESKTOP_FILE_APP_NAME + OR NOT ARGS_DESKTOP_FILE_CMD) + message(FATAL_ERROR "Not all mandatory arguments specified.") + endif () + if (NOT ARGS_DESKTOP_FILE_GENERIC_NAME) + set(ARGS_DESKTOP_FILE_GENERIC_NAME "${ARGS_DESKTOP_FILE_APP_NAME}") + endif () + + # create desktop file from template + configure_file("${APP_DESKTOP_TEMPLATE_FILE}" "${CMAKE_CURRENT_BINARY_DIR}/resources/${ARGS_FILE_NAME}.desktop") + # add install for the desktop file + install( + FILES "${CMAKE_CURRENT_BINARY_DIR}/resources/${ARGS_FILE_NAME}.desktop" + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/applications" + COMPONENT desktop) +endfunction () + +# define function to add appstream file +function (add_appstream_file) + # read body for appstream desktop file from resources + set(META_APP_APPDATA_BODY_FILE "${CMAKE_CURRENT_SOURCE_DIR}/resources/body.appdata.xml") + set(META_APP_APPDATA_SUBSTITUTED_BODY_FILE "${CMAKE_CURRENT_BINARY_DIR}/resources/${META_ID}.body.appdata.xml") + if (EXISTS "${META_APP_APPDATA_BODY_FILE}") + configure_file("${META_APP_APPDATA_BODY_FILE}" "${META_APP_APPDATA_SUBSTITUTED_BODY_FILE}" @ONLY) + file(READ "${META_APP_APPDATA_SUBSTITUTED_BODY_FILE}" META_APP_APPDATA_BODY) + # add indentation of two additional spaces + string(REGEX REPLACE "\n([^$])" "\n \\1" META_APP_APPDATA_BODY "${META_APP_APPDATA_BODY}") + endif () + + # create appstream desktop file from template + set(APPSTREAM_FILE "${CMAKE_CURRENT_BINARY_DIR}/resources/${META_ID}.appdata.xml") + configure_file("${APP_APPSTREAM_TEMPLATE_FILE}" "${APPSTREAM_FILE}" @ONLY) + + # add install for the appstream file + install( + FILES "${APPSTREAM_FILE}" + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/metainfo" + COMPONENT appimage) +endfunction () + +# define function to add *.desktop file and meta info from project meta data +function (add_desktop_file) + # skip if not building with GUI support + if (NOT META_DESKTOP_FILE_FOR_CLI AND ((NOT DEFINED META_GUI_OPTIONAL OR META_GUI_OPTIONAL) AND NOT (WIDGETS_GUI + OR QUICK_GUI))) + return() + endif () + + # compose actions + set(DESKTOP_FILE_ADDITIONAL_ENTRIES "") + foreach (ACTION_VAR ${META_APP_ACTIONS}) + list(GET META_APP_ACTION_${ACTION_VAR} 0 ACTION_ID) + list(GET META_APP_ACTION_${ACTION_VAR} 1 ACTION_NAME) + list(GET META_APP_ACTION_${ACTION_VAR} 2 ACTION_ARGS) + set(DESKTOP_FILE_ADDITIONAL_ENTRIES + "${DESKTOP_FILE_ADDITIONAL_ENTRIES}\n[Desktop Action ${ACTION_ID}]\nName=${ACTION_NAME}\nExec=${META_TARGET_NAME} ${ACTION_ARGS}" + ) + endforeach () + + # create desktop file + add_custom_desktop_file( + FILE_NAME + "${META_ID}" + DESKTOP_FILE_APP_NAME + "${META_APP_NAME}" + DESKTOP_FILE_GENERIC_NAME + "${META_GENERIC_NAME}" + DESKTOP_FILE_DESCRIPTION + "${META_APP_DESCRIPTION}" + DESKTOP_FILE_CATEGORIES + "${META_APP_CATEGORIES}" + DESKTOP_FILE_CMD + "${META_TARGET_NAME}" + DESKTOP_FILE_ICON + "${NAMESPACE_PREFIX}${META_PROJECT_NAME}${META_CONFIG_SUFFIX}" + DESKTOP_FILE_ADDITIONAL_ENTRIES + "${DESKTOP_FILE_ADDITIONAL_ENTRIES}") + + add_appstream_file() +endfunction ()