Warning, /frameworks/kcmutils/KF6KCMUtilsMacros.cmake is written in an unsupported language. File is not indexed.
0001 # SPDX-FileCopyrightText: 2022 Alexander Lohnau <alexander.lohnau@gmx.de>
0002 # SPDX-License-Identifier: BSD-3-Clause
0003
0004 #.rst:
0005 # KF6KCMUtilsGenerateModuleData
0006 # ---------------------------
0007 #
0008 # This module provides the ``kcmutils_generate_module_data`` function for
0009 # generating basic module data classes. Class derivated from KCModuleData
0010 # ::
0011 #
0012 # kcmutils_generate_module_data(<sources_var | target_name (since 6.0)>
0013 # MODULE_DATA_CLASS_NAME <class_name>
0014 # MODULE_DATA_HEADER <header_file_name>
0015 # SETTINGS_HEADERS <setting_header.h> [<second_setting_header.h> [...]]]
0016 # SETTINGS_CLASSES <SettingClass> [<SecondSettingClass> [...]]]
0017 # )
0018 #
0019 # A header file, ``<header_file_name>``, will be generated along with a corresponding
0020 # source file, which will be added to ``<sources_var>``. These will provide a
0021 # KCModuleData that can be referred to from C++ code using ``<class_name>``.
0022 # This module will autoregister settings declared on ``setting_header.h`` with class name ``SettingClass``.
0023 # Multiple settings classes / settings headers can be specified.
0024
0025 include(CMakeParseArguments)
0026
0027 set(_KCMODULE_DATA_TEMPLATE_CPP "${CMAKE_CURRENT_LIST_DIR}/kcmutilsgeneratemoduledata.cpp.in")
0028 set(_KCMODULE_DATA_TEMPLATE_H "${CMAKE_CURRENT_LIST_DIR}/kcmutilsgeneratemoduledata.h.in")
0029
0030 function(kcmutils_generate_module_data sources_var)
0031 set(options)
0032 set(oneValueArgs MODULE_DATA_CLASS_NAME MODULE_DATA_HEADER NAMESPACE)
0033 set(multiValueArgs SETTINGS_HEADERS SETTINGS_CLASSES)
0034 cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
0035
0036 if(ARG_UNPARSED_ARGUMENTS)
0037 message(FATAL_ERROR "Unexpected arguments to kcmutils_generate_module_data: ${ARG_UNPARSED_ARGUMENTS}")
0038 endif()
0039 if(NOT ARG_MODULE_DATA_HEADER)
0040 message(FATAL_ERROR "Missing MODULE_DATA_HEADER argument for kcmutils_generate_module_data")
0041 endif()
0042
0043 if(NOT ARG_MODULE_DATA_CLASS_NAME)
0044 message(FATAL_ERROR "Missing MODULE_DATA_CLASS_NAME argument for kcmutils_generate_module_data")
0045 endif()
0046
0047 if(NOT ARG_SETTINGS_HEADERS)
0048 message(FATAL_ERROR "Missing SETTINGS_HEADERS argument for kcmutils_generate_module_data")
0049 endif()
0050
0051 if(NOT ARG_SETTINGS_CLASSES)
0052 message(FATAL_ERROR "Missing SETTINGS_CLASSES argument for kcmutils_generate_module_data")
0053 endif()
0054
0055 set(MODULE_DATA_CLASS_NAME ${ARG_MODULE_DATA_CLASS_NAME})
0056 get_filename_component(HEADER_NAME "${ARG_MODULE_DATA_HEADER}" NAME)
0057
0058 string(REGEX REPLACE "[^a-zA-Z0-9]" "_" GUARD_NAME "${HEADER_NAME}")
0059 string(TOUPPER "${GUARD_NAME}" GUARD_NAME)
0060
0061 string(FIND "${ARG_MODULE_DATA_HEADER}" "." pos REVERSE)
0062 if (pos EQUAL -1)
0063 set(CPP_FILENAME "${ARG_MODULE_DATA_HEADER}.cpp")
0064 else()
0065 string(SUBSTRING "${ARG_MODULE_DATA_HEADER}" 0 ${pos} base_filename)
0066 set(CPP_FILENAME "${base_filename}.cpp")
0067 endif()
0068
0069 set(INCLUDES_SETTINGS)
0070 foreach(_header ${ARG_SETTINGS_HEADERS})
0071 set(INCLUDES_SETTINGS "${INCLUDES_SETTINGS}#include \"${_header}\"\n")
0072 endforeach()
0073
0074 set(SETTINGS_FORWARD_DECLARATION)
0075 set(SETTINGS_CONSTRUCTOR_INITIALIZATION)
0076 set(SETTINGS_METHOD_DEFINITION)
0077 set(SETTINGS_METHOD_DECLARATION)
0078 list(LENGTH ARG_SETTINGS_CLASSES _nb_settings)
0079 foreach(_class ${ARG_SETTINGS_CLASSES})
0080 if(_nb_settings EQUAL 1)
0081 set(_setting_attribute "m_settings")
0082 set(_setting_getter "settings")
0083 else()
0084 # lower first letter
0085 string(SUBSTRING ${_class} 0 1 _first_letter)
0086 string(TOLOWER ${_first_letter} _first_letter)
0087 string(REGEX REPLACE "^.(.*)" "${_first_letter}\\1" _method_name "${_class}")
0088 set(_setting_attribute "m_${_method_name}")
0089 set(_setting_getter "${_method_name}")
0090 endif()
0091
0092 set(SETTINGS_FORWARD_DECLARATION "${SETTINGS_FORWARD_DECLARATION}class ${_class};\n")
0093 set(SETTINGS_CONSTRUCTOR_INITIALIZATION "${SETTINGS_CONSTRUCTOR_INITIALIZATION}, ${_setting_attribute}(new ${_class}(this))\n")
0094 set(SETTINGS_METHOD_DECLARATION "${SETTINGS_METHOD_DECLARATION}${_class} *${_setting_getter}() const;\n")
0095 set(SETTINGS_ATTRIBUTE_DECLARATION "${SETTINGS_ATTRIBUTE_DECLARATION}${_class} *${_setting_attribute};\n")
0096 set(SETTINGS_METHOD_DEFINITION "${SETTINGS_METHOD_DEFINITION}${_class} *${ARG_MODULE_DATA_CLASS_NAME}::${_setting_getter}() const
0097 {
0098 return ${_setting_attribute};
0099 }\n\n")
0100 endforeach()
0101
0102 if(ARG_NAMESPACE)
0103 set(OPEN_NAMESPACE "namespace ${ARG_NAMESPACE} {")
0104 set(CLOSE_NAMESPACE "}")
0105 endif()
0106 configure_file("${_KCMODULE_DATA_TEMPLATE_CPP}" "${CPP_FILENAME}")
0107 configure_file("${_KCMODULE_DATA_TEMPLATE_H}" "${ARG_MODULE_DATA_HEADER}")
0108
0109 if (TARGET ${sources_var})
0110 target_sources(${sources_var} PRIVATE "${CPP_FILENAME}")
0111 else()
0112 set(sources "${${sources_var}}")
0113 list(APPEND sources "${CPP_FILENAME}")
0114 set(${sources_var} "${sources}" PARENT_SCOPE)
0115 endif()
0116 endfunction()
0117
0118
0119 # kcmutils_generate_desktop_file(kcm_target_nam)
0120 #
0121 # This macro generates a desktop file for the given KCM.
0122 # This desktop file has the following attributes:
0123 # Type=Application
0124 # NoDisplay=true
0125 # Icon=icon from the .json file
0126 # Name=name from the .json file
0127 # Name[foo]=translated name from the .json file
0128 # and an Exec launching it in systemsettings
0129 # The .json file must have the same basename as the kcm_target parameter.
0130 # Since 5.97
0131
0132 function(kcmutils_generate_desktop_file kcm_target)
0133 set(OUT_FILE ${CMAKE_CURRENT_BINARY_DIR}/${kcm_target}.desktop)
0134 set(IN_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${kcm_target}.json)
0135 if (NOT EXISTS ${IN_FILE})
0136 message(FATAL_ERROR "Could not find metadata file for ${kcm_target}, expected path was ${IN_FILE}")
0137 endif()
0138
0139 set(IN_SOURCE_DESKTOP_FILE ${CMAKE_CURRENT_SOURCE_DIR}/${kcm_target}.desktop)
0140 if (EXISTS ${IN_SOURCE_DESKTOP_FILE})
0141 message(FATAL_ERROR "A metadata desktop file for the KCM already exists in ${IN_SOURCE_DESKTOP_FILE} Remove this file or remove the method call to generate_kcm_desktop_file")
0142 endif()
0143
0144 if(NOT KDE_INSTALL_APPDIR)
0145 include(KDEInstallDirs)
0146 endif()
0147
0148 add_custom_target(${kcm_target}-kcm-desktop-gen
0149 COMMAND KF6::kcmdesktopfilegenerator ${IN_FILE} ${OUT_FILE}
0150 DEPENDS ${IN_FILE})
0151 add_dependencies(${kcm_target} ${kcm_target}-kcm-desktop-gen)
0152 if (NOT KCMUTILS_INTERNAL_TEST_MODE)
0153 install(FILES ${OUT_FILE} DESTINATION ${KDE_INSTALL_APPDIR})
0154 endif()
0155 endfunction()
0156
0157 # kcmutils_add_qml_kcm(target_name [SOURCES <src> [...]] [INSTALL_NAMESPACE "plasma/kcms/somesubdir"] [DISABLE_DESKTOP_FILE_GENERATION])
0158 #
0159 # Since 6.0
0160 function(kcmutils_add_qml_kcm target_name)
0161 set(options DISABLE_DESKTOP_FILE_GENERATION)
0162 set(oneValueArgs INSTALL_NAMESPACE)
0163 set(multiValueArgs SOURCES)
0164 cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
0165 if (NOT ARG_INSTALL_NAMESPACE)
0166 set(ARG_INSTALL_NAMESPACE plasma/kcms/systemsettings)
0167 endif()
0168
0169 kcoreaddons_add_plugin(${target_name} INSTALL_NAMESPACE ${ARG_INSTALL_NAMESPACE} SOURCES ${ARG_SOURCES})
0170 if (NOT ARG_DISABLE_DESKTOP_FILE_GENERATION)
0171 kcmutils_generate_desktop_file(${target_name})
0172 endif()
0173 # Hardcode the "ui" filder for now
0174 __kcmutils_target_qml_sources(${target_name} "kcm/${target_name}" "ui")
0175 endfunction()
0176
0177 function(__kcmutils_target_qml_sources target_name kcm_qrc_prefix qml_sources_dir)
0178 file(GLOB_RECURSE files CONFIGURE_DEPENDS "${CMAKE_CURRENT_SOURCE_DIR}/${qml_sources_dir}/*")
0179 if (NOT files)
0180 message(FATAL_ERROR "Could not find any files in ${CMAKE_CURRENT_SOURCE_DIR}/${qml_sources_dir}/*")
0181 endif()
0182
0183 set(_qrc_template "<!-- This file was automatically generated by kcmutils_add_qml_kcm and should not be modified -->")
0184 string(APPEND _qrc_template "\n<RCC>\n<qresource prefix=\"/${kcm_qrc_prefix}\">")
0185 foreach(file_path ${files})
0186 string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}/${qml_sources_dir}/" "" file_qrc_path "${file_path}")
0187 string(APPEND _qrc_template "\n<file alias=\"${file_qrc_path}\">${file_path}</file>")
0188 endforeach()
0189
0190 string(APPEND _qrc_template "\n</qresource>\n</RCC>\n")
0191
0192 set(WORK_FILE "${CMAKE_CURRENT_BINARY_DIR}/_generated${target_name}.qrc")
0193 set(COMPILE_FILE "${CMAKE_CURRENT_BINARY_DIR}/${target_name}.qrc")
0194 file(WRITE "${WORK_FILE}" "${_qrc_template}")
0195 execute_process(COMMAND ${CMAKE_COMMAND} -E copy_if_different "${WORK_FILE}" "${COMPILE_FILE}")
0196 qt_add_resources(_qrc_output "${COMPILE_FILE}")
0197
0198 target_sources(${target_name} PRIVATE ${_qrc_output})
0199 endfunction()