Warning, /frameworks/extra-cmake-modules/modules/ECMSetupQtPluginMacroNames.cmake is written in an unsupported language. File is not indexed.

0001 # SPDX-FileCopyrightText: 2018 Friedrich W. H. Kossebau <kossebau@kde.org>
0002 #
0003 # SPDX-License-Identifier: BSD-3-Clause
0004 
0005 #[=======================================================================[.rst:
0006 ECMSetupQtPluginMacroNames
0007 --------------------------
0008 
0009 Instruct CMake's automoc about C++ preprocessor macros used to define Qt-style plugins.
0010 
0011 ::
0012 
0013   ecm_setup_qtplugin_macro_names(
0014       [JSON_NONE <macro_name> [<macro_name> [...]]]
0015       [JSON_ARG1 <macro_name> [<macro_name> [...]]]
0016       [JSON_ARG2 <macro_name> [<macro_name> [...]]]
0017       [JSON_ARG3 <macro_name> [<macro_name> [...]]]
0018       [CONFIG_CODE_VARIABLE <variable_name>] )
0019 
0020 CMake's automoc needs some support when parsing C++ source files to detect whether moc
0021 should be run on those files and if there are also dependencies on other files, like those
0022 with Qt plugin metadata in JSON format. Because automoc just greps overs the raw plain text
0023 of the sources without any C++ preprocessor-like processing.
0024 CMake in newer versions provides the variables ``CMAKE_AUTOMOC_DEPEND_FILTERS`` (CMake >= 3.9.0)
0025 and ``CMAKE_AUTOMOC_MACRO_NAMES`` (CMake >= 3.10) to allow the developer to assist automoc.
0026 
0027 This macro cares for the explicit setup needed for those variables for common cases of
0028 C++ preprocessor macros used for Qt-style plugins.
0029 
0030 ``JSON_NONE`` lists the names of C++ preprocessor macros for Qt-style plugins which do not refer to
0031 external files with the plugin metadata.
0032 
0033 ``JSON_ARG1`` lists the names of C++ preprocessor macros for Qt-style plugins where the first argument
0034 to the macro is the name of the external file with the plugin metadata.
0035 
0036 ``JSON_ARG2`` is the same as ``JSON_ARG1`` but with the file name being the second argument.
0037 
0038 ``JSON_ARG3`` is the same as ``JSON_ARG1`` but with the file name being the third argument.
0039 
0040 ``CONFIG_CODE_VARIABLE`` specifies the name of the variable which will get set as
0041 value some generated CMake code for instructing automoc for the given macro names,
0042 as useful in an installed CMake config file. The variable can then be used as usual in
0043 the template file for such a CMake config file, by ``@<variable_name>@``.
0044 
0045 
0046 Example usage:
0047 
0048 Given some plugin-oriented Qt-based software which defines a custom C++ preprocessor
0049 macro ``EXPORT_MYPLUGIN`` for declaring the central plugin object:
0050 
0051 .. code-block:: c++
0052 
0053   #define EXPORT_MYPLUGIN_WITH_JSON(classname, jsonFile) \
0054   class classname : public QObject \
0055   { \
0056       Q_OBJECT \
0057       Q_PLUGIN_METADATA(IID "myplugin" FILE jsonFile) \
0058       explicit classname() {} \
0059   };
0060 
0061 In the CMake buildsystem of the library one calls
0062 
0063 .. code-block:: cmake
0064 
0065   ecm_setup_qtplugin_macro_names(
0066       JSON_ARG2
0067          EXPORT_MYPLUGIN_WITH_JSON
0068   )
0069 
0070 to instruct automoc about the usage of that macro in the sources of the
0071 library itself.
0072 
0073 Given the software installs a library including the header with the macro
0074 definition and a CMake config file, so 3rd-party can create additional
0075 plugins by linking against the library, one passes additionally the name of
0076 a variable which shall be set as value the CMake code needed to instruct
0077 automoc about the usage of that macro.
0078 
0079 .. code-block:: cmake
0080 
0081   ecm_setup_qtplugin_macro_names(
0082       JSON_ARG2
0083          EXPORT_MYPLUGIN_WITH_JSON
0084       CONFIG_CODE_VARIABLE
0085          PACKAGE_SETUP_AUTOMOC_VARIABLES
0086   )
0087 
0088 This variable then is used in the template file (e.g.
0089 ``MyProjectConfig.cmake.in``) for the libary's installed CMake config file
0090 and that way will ensure that in the 3rd-party plugin's buildsystem
0091 automoc is instructed as well as needed:
0092 
0093 ::
0094 
0095   @PACKAGE_SETUP_AUTOMOC_VARIABLES@
0096 
0097 Since 5.45.0.
0098 #]=======================================================================]
0099 
0100 include(CMakePackageConfigHelpers)
0101 
0102 macro(ecm_setup_qtplugin_macro_names)
0103     set(options )
0104     set(oneValueArgs CONFIG_CODE_VARIABLE)
0105     set(multiValueArgs JSON_NONE JSON_ARG1 JSON_ARG2 JSON_ARG3)
0106 
0107     cmake_parse_arguments(ESQMN "${options}" "${oneValueArgs}" "${multiValueArgs}"  ${ARGN})
0108 
0109     if(ESQMN_UNPARSED_ARGUMENTS)
0110         message(FATAL_ERROR "Unknown keywords given to ECM_SETUP_QTPLUGIN_MACRO_NAMES(): \"${ESQMN_UNPARSED_ARGUMENTS}\"")
0111     endif()
0112 
0113     # CMAKE_AUTOMOC_MACRO_NAMES
0114     list(APPEND CMAKE_AUTOMOC_MACRO_NAMES
0115         ${ESQMN_JSON_NONE}
0116         ${ESQMN_JSON_ARG1}
0117         ${ESQMN_JSON_ARG2}
0118         ${ESQMN_JSON_ARG3}
0119     )
0120 
0121     # CMAKE_AUTOMOC_DEPEND_FILTERS
0122     # CMake's automoc needs help to find names of plugin metadata files in case Q_PLUGIN_METADATA
0123     # is indirectly used via other C++ preprocessor macros
0124     foreach(macro_name  ${ESQMN_JSON_ARG1})
0125         list(APPEND CMAKE_AUTOMOC_DEPEND_FILTERS
0126             "${macro_name}"
0127             "[\n^][ \t]*${macro_name}[ \t\n]*\\([ \t\n]*\"([^\"]+)\""
0128         )
0129     endforeach()
0130     foreach(macro_name  ${ESQMN_JSON_ARG2})
0131         list(APPEND CMAKE_AUTOMOC_DEPEND_FILTERS
0132             "${macro_name}"
0133             "[\n^][ \t]*${macro_name}[ \t\n]*\\([^,]*,[ \t\n]*\"([^\"]+)\""
0134         )
0135     endforeach()
0136     foreach(macro_name  ${ESQMN_JSON_ARG3})
0137         list(APPEND CMAKE_AUTOMOC_DEPEND_FILTERS
0138             "${macro_name}"
0139             "[\n^][ \t]*${macro_name}[ \t\n]*\\([^,]*,[^,]*,[ \t\n]*\"([^\"]+)\""
0140         )
0141     endforeach()
0142 
0143     if (ESQMN_CONFIG_CODE_VARIABLE)
0144         # As CMake config files of one project can be included multiple times,
0145         # the code to add entries to CMAKE_AUTOMOC_MACRO_NAMES & CMAKE_AUTOMOC_DEPEND_FILTERS
0146         # would then be also executed multiple times.
0147         # While there currently is no simple way known to have a unique flag to track
0148         # if the code was already executed, at least by the data currently passed to this macro,
0149         # simply check for the presence of the new entries  before adding them for now.
0150         # Not using IN_LIST in generated code, as projects might have CMP0057 set to OLD
0151         set(_content
0152 "####################################################################################
0153 # CMAKE_AUTOMOC
0154 ")
0155         set(_all_macro_names
0156             ${ESQMN_JSON_NONE}
0157             ${ESQMN_JSON_ARG1}
0158             ${ESQMN_JSON_ARG2}
0159             ${ESQMN_JSON_ARG3}
0160         )
0161         string(APPEND _content "
0162 # CMake 3.9+ warns about automoc on files without Q_OBJECT, and doesn't know about other macros.
0163 # 3.10+ lets us provide more macro names that require automoc.
0164 foreach(macro_name  ${_all_macro_names})
0165     # we can be run multiple times, so add only once
0166     list (FIND CMAKE_AUTOMOC_MACRO_NAMES \"\${macro_name}\" _index)
0167     if(_index LESS 0)
0168         list(APPEND CMAKE_AUTOMOC_MACRO_NAMES \${macro_name})
0169     endif()
0170 endforeach()
0171 ")
0172 
0173         if(ESQMN_JSON_ARG1 OR ESQMN_JSON_ARG2 OR ESQMN_JSON_ARG3)
0174             string(APPEND _content "
0175 # CMake's automoc needs help to find names of plugin metadata files in case Q_PLUGIN_METADATA
0176 # is indirectly used via other C++ preprocessor macros
0177 ")
0178             if(ESQMN_JSON_ARG1)
0179                 string(APPEND _content
0180 "foreach(macro_name  ${ESQMN_JSON_ARG1})
0181     # we can be run multiple times, so add only once
0182     list (FIND CMAKE_AUTOMOC_DEPEND_FILTERS \"\${macro_name}\" _index)
0183     if(_index LESS 0)
0184         list(APPEND CMAKE_AUTOMOC_DEPEND_FILTERS
0185             \"\${macro_name}\"
0186             \"[\\n^][ \\t]*\${macro_name}[ \\t\\n]*\\\\([ \\t\\n]*\\\"([^\\\"]+)\\\"\"
0187         )
0188     endif()
0189 endforeach()
0190 ")
0191             endif()
0192             if(ESQMN_JSON_ARG2)
0193                 string(APPEND _content
0194 "foreach(macro_name  ${ESQMN_JSON_ARG2})
0195     # we can be run multiple times, so add only once
0196     list (FIND CMAKE_AUTOMOC_DEPEND_FILTERS \"\${macro_name}\" _index)
0197     if(_index LESS 0)
0198         list(APPEND CMAKE_AUTOMOC_DEPEND_FILTERS
0199             \"\${macro_name}\"
0200             \"[\\n^][ \\t]*\${macro_name}[ \\t\\n]*\\\\([^,]*,[ \\t\\n]*\\\"([^\\\"]+)\\\"\"
0201         )
0202     endif()
0203 endforeach()
0204 ")
0205             endif()
0206             if(ESQMN_JSON_ARG3)
0207                 string(APPEND _content
0208 "foreach(macro_name  ${ESQMN_JSON_ARG3})
0209     # we can be run multiple times, so add only once
0210     list (FIND CMAKE_AUTOMOC_DEPEND_FILTERS \"\${macro_name}\" _index)
0211     if(_index LESS 0)
0212         list(APPEND CMAKE_AUTOMOC_DEPEND_FILTERS
0213             \"\${macro_name}\"
0214             \"[\\n^][ \\t]*\${macro_name}[ \\t\\n]*\\\\([^,]*,[^,]*,[ \\t\\n]*\\\"([^\\\"]+)\\\"\"
0215         )
0216     endif()
0217 endforeach()
0218 ")
0219             endif()
0220         endif()
0221         string(APPEND _content "
0222 ####################################################################################"
0223         )
0224 
0225         set(${ESQMN_CONFIG_CODE_VARIABLE} ${_content})
0226     endif()
0227 endmacro()