Warning, /frameworks/extra-cmake-modules/modules/ECMQmlModule5.cmake is written in an unsupported language. File is not indexed.
0001 # 0002 # SPDX-FileCopyrightText: 2021 Arjen Hiemstra <ahiemstra@heimr.nl> 0003 # 0004 # SPDX-License-Identifier: BSD-3-Clause 0005 0006 # Qt 5 implementation of ECMQmlModule 0007 0008 set(_ECM_QMLMODULE_STATIC_QMLONLY_H "${CMAKE_CURRENT_LIST_DIR}/ECMQmlModule.h.in") 0009 set(_ECM_QMLMODULE_STATIC_QMLONLY_CPP "${CMAKE_CURRENT_LIST_DIR}/ECMQmlModule.cpp.in") 0010 0011 set(_ECM_QMLMODULE_PROPERTY_URI "_ecm_qml_uri") 0012 set(_ECM_QMLMODULE_PROPERTY_QMLDIR "_ecm_qmldir_file") 0013 set(_ECM_QMLMODULE_PROPERTY_FILES "_ecm_qml_files") 0014 set(_ECM_QMLMODULE_PROPERTY_QMLONLY "_ecm_qml_only") 0015 set(_ECM_QMLMODULE_PROPERTY_VERSION "_ecm_qml_version") 0016 set(_ECM_QMLMODULE_PROPERTY_PRIVATE "_ecm_qml_private") 0017 set(_ECM_QMLMODULE_PROPERTY_PATH "_ecm_qml_path") 0018 set(_ECM_QMLMODULE_PROPERTY_CLASSNAME "_ecm_qml_classname") 0019 set(_ECM_QMLMODULE_PROPERTY_DEPENDS "_ecm_qml_depends") 0020 0021 macro(_ecm_qmlmodule_verify_qml_target ARG_TARGET) 0022 if (NOT TARGET ${ARG_TARGET}) 0023 message(FATAL_ERROR "Target ${ARG_TARGET} does not exist") 0024 endif() 0025 get_target_property(_qml_uri ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_URI}) 0026 if ("${_qml_uri}" STREQUAL "" OR "${_qml_uri}" STREQUAL "${_ECM_QMLMODULE_PROPERTY_URI}-NOTFOUND") 0027 message(FATAL_ERROR "Target ${ARG_TARGET} is not a QML plugin target") 0028 endif() 0029 endmacro() 0030 0031 function(_ecm_qmlmodule_generate_qmldir ARG_TARGET) 0032 get_target_property(_qml_uri ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_URI}) 0033 get_target_property(_qml_files ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_FILES}) 0034 get_target_property(_qml_only ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_QMLONLY}) 0035 get_target_property(_qml_classname ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_CLASSNAME}) 0036 0037 set(_qmldir_template "# This file was automatically generated by ECMQmlModule and should not be modified") 0038 0039 string(APPEND _qmldir_template "\nmodule ${_qml_uri}") 0040 0041 if (NOT ${_qml_only}) 0042 string(APPEND _qmldir_template "\nplugin ${ARG_TARGET}") 0043 0044 if ("${_qml_classname}" STREQUAL "") 0045 string(APPEND _qmldir_template "\nclassname ${ARG_TARGET}") 0046 else() 0047 string(APPEND _qmldir_template "\nclassname ${_qml_classname}") 0048 endif() 0049 endif() 0050 0051 get_target_property(_qml_depends ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_DEPENDS}) 0052 if (NOT "${_qml_depends}" STREQUAL "") 0053 foreach(_depends ${_qml_depends}) 0054 string(APPEND _qmldir_template "\ndepends ${_depends}") 0055 endforeach() 0056 endif() 0057 0058 foreach(_file ${_qml_files}) 0059 get_filename_component(_filename ${_file} NAME) 0060 get_filename_component(_classname ${_file} NAME_WE) 0061 get_property(_version SOURCE ${_file} PROPERTY ${_ECM_QMLMODULE_PROPERTY_VERSION}) 0062 get_property(_private SOURCE ${_file} PROPERTY ${_ECM_QMLMODULE_PROPERTY_PRIVATE}) 0063 get_property(_singleton SOURCE ${_file} PROPERTY "QT_QML_SINGLETON_TYPE") 0064 get_property(_path SOURCE ${_file} PROPERTY ${_ECM_QMLMODULE_PROPERTY_PATH}) 0065 cmake_path(SET _actual_path "${_path}") 0066 cmake_path(APPEND _actual_path "${_filename}") 0067 if (_singleton) 0068 string(APPEND _qmldir_template "\nsingleton ${_classname} ${_version} ${_actual_path}") 0069 else() 0070 if (NOT _private) 0071 string(APPEND _qmldir_template "\n${_classname} ${_version} ${_actual_path}") 0072 else() 0073 string(APPEND _qmldir_template "\ninternal ${_classname} ${_actual_path}") 0074 endif() 0075 endif() 0076 endforeach() 0077 get_target_property(_qml_version ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_VERSION}) 0078 string(APPEND _qmldir_template "\n# KDE-qmldir-Version: ${_qml_version}") 0079 0080 string(APPEND _qmldir_template "\n") 0081 0082 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${ARG_TARGET}_qmldir" "${_qmldir_template}") 0083 set_target_properties(${ARG_TARGET} PROPERTIES _ecm_qmldir_file "${CMAKE_CURRENT_BINARY_DIR}/${ARG_TARGET}_qmldir") 0084 endfunction() 0085 0086 function(_ecm_qmlmodule_generate_qrc ARG_TARGET) 0087 get_target_property(_qml_uri ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_URI}) 0088 get_target_property(_qml_files ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_FILES}) 0089 get_target_property(_qmldir_file ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_QMLDIR}) 0090 get_target_property(_qml_version ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_VERSION}) 0091 0092 _ecm_qmlmodule_uri_to_path(_qml_prefix "${_qml_uri}" "${_qml_version}") 0093 0094 set(_qrc_template "<!-- This file was automatically generated by ECMQmlModule and should not be modified -->") 0095 0096 string(APPEND _qrc_template "\n<RCC>\n<qresource prefix=\"/qt-project.org/imports/${_qml_prefix}\">") 0097 string(APPEND _qrc_template "\n<file alias=\"qmldir\">${_qmldir_file}</file>") 0098 0099 foreach(_file ${_qml_files}) 0100 get_filename_component(_filename ${_file} NAME) 0101 get_property(_path SOURCE ${_file} PROPERTY ${_ECM_QMLMODULE_PROPERTY_PATH}) 0102 0103 set(_file_path "${_filename}") 0104 if (NOT "${_path}" STREQUAL "") 0105 set(_file_path "${_path}/${_filename}") 0106 endif() 0107 0108 string(APPEND _qrc_template "\n<file alias=\"${_file_path}\">${_file}</file>") 0109 endforeach() 0110 0111 string(APPEND _qrc_template "\n</qresource>\n</RCC>\n") 0112 0113 file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${ARG_TARGET}.qrc" "${_qrc_template}") 0114 qt_add_resources(_qrc_output "${CMAKE_CURRENT_BINARY_DIR}/${ARG_TARGET}.qrc") 0115 0116 target_sources(${ARG_TARGET} PRIVATE ${_qrc_output}) 0117 endfunction() 0118 0119 function(ecm_add_qml_module ARG_TARGET) 0120 cmake_parse_arguments(PARSE_ARGV 1 ARG "NO_PLUGIN" "URI;VERSION;CLASSNAME" "") 0121 0122 if ("${ARG_TARGET}" STREQUAL "") 0123 message(FATAL_ERROR "ecm_add_qml_module called without a valid target name.") 0124 endif() 0125 0126 if ("${ARG_URI}" STREQUAL "") 0127 message(FATAL_ERROR "ecm_add_qml_module called without a valid module URI.") 0128 endif() 0129 0130 string(FIND "${ARG_URI}" " " "_space") 0131 if (${_space} GREATER_EQUAL 0) 0132 message(FATAL_ERROR "ecm_add_qml_module called without a valid module URI.") 0133 endif() 0134 0135 if (${BUILD_SHARED_LIBS} AND ${ARG_NO_PLUGIN}) 0136 # CMake doesn't like library targets without sources, so if we have no 0137 # C++ sources, use a plain target that we can add all the install stuff 0138 # to. 0139 add_custom_target(${ARG_TARGET} ALL) 0140 else() 0141 add_library(${ARG_TARGET}) 0142 endif() 0143 0144 if (NOT ARG_VERSION) 0145 set(ARG_VERSION "1.0") 0146 endif() 0147 0148 set_target_properties(${ARG_TARGET} PROPERTIES 0149 ${_ECM_QMLMODULE_PROPERTY_URI} "${ARG_URI}" 0150 ${_ECM_QMLMODULE_PROPERTY_FILES} "" 0151 ${_ECM_QMLMODULE_PROPERTY_QMLONLY} "${ARG_NO_PLUGIN}" 0152 ${_ECM_QMLMODULE_PROPERTY_VERSION} "${ARG_VERSION}" 0153 ${_ECM_QMLMODULE_PROPERTY_CLASSNAME} "${ARG_CLASSNAME}" 0154 ${_ECM_QMLMODULE_PROPERTY_DEPENDS} "" 0155 ) 0156 0157 # QQmlImportDatabase::resolvePlugin doesn't accept lib prefixes under 0158 # Windows, causing to fail to import when using as a dynamic plugin. 0159 if (MINGW) 0160 set_target_properties(${ARG_TARGET} PROPERTIES PREFIX "") 0161 endif() 0162 0163 # -Muri is required for static QML plugins to work properly, see 0164 # https://bugreports.qt.io/browse/QTBUG-82598 0165 set_target_properties(${ARG_TARGET} PROPERTIES AUTOMOC_MOC_OPTIONS -Muri=${ARG_URI}) 0166 endfunction() 0167 0168 function(ecm_add_qml_module_dependencies ARG_TARGET) 0169 cmake_parse_arguments(PARSE_ARGV 1 ARG "" "" "DEPENDS") 0170 0171 _ecm_qmlmodule_verify_qml_target(${ARG_TARGET}) 0172 0173 if ("${ARG_DEPENDS}" STREQUAL "") 0174 message(FATAL_ERROR "ecm_add_qml_module_dependencies called without required argument DEPENDS") 0175 endif() 0176 0177 set_target_properties(${ARG_TARGET} PROPERTIES ${_ECM_QMLMODULE_PROPERTY_DEPENDS} "${ARG_DEPENDS}") 0178 endfunction() 0179 0180 function(ecm_target_qml_sources ARG_TARGET) 0181 cmake_parse_arguments(PARSE_ARGV 1 ARG "PRIVATE" "VERSION;PATH" "SOURCES") 0182 0183 _ecm_qmlmodule_verify_qml_target(${ARG_TARGET}) 0184 0185 if ("${ARG_SOURCES}" STREQUAL "") 0186 message(FATAL_ERROR "ecm_target_qml_sources called without required argument SOURCES") 0187 endif() 0188 0189 if ("${ARG_VERSION}" STREQUAL "") 0190 get_target_property(ARG_VERSION ${ARG_TARGET} "_ecm_qml_version") 0191 endif() 0192 # In case we have not specified a version in add_qml_module, we use 1.0 as a default for the individual QML files 0193 if (NOT ARG_VERSION) 0194 set(ARG_VERSION "1.0") 0195 endif() 0196 0197 foreach(_file ${ARG_SOURCES}) 0198 # Check if a given file exists, but only for files that are not 0199 # automatically generated. 0200 set(_path "${_file}") 0201 get_source_file_property(_generated ${_file} GENERATED) 0202 if (NOT _generated) 0203 if (IS_ABSOLUTE ${_path}) 0204 # Assume absolute paths are generated, which may not always be 0205 # true but is fairly likely. 0206 set(_generated TRUE) 0207 else() 0208 string(FIND ${_file} ${CMAKE_BINARY_DIR} _in_binary_dir) 0209 if (${_in_binary_dir} GREATER_EQUAL 0) 0210 # Assume anything in binary dir is generated. 0211 set(_generated TRUE) 0212 else() 0213 set(_path "${CMAKE_CURRENT_SOURCE_DIR}/${_file}") 0214 endif() 0215 endif() 0216 endif() 0217 0218 if (NOT ${_generated} AND NOT EXISTS ${_path}) 0219 message(FATAL_ERROR "ecm_target_qml_sources called with nonexistent file ${_file}") 0220 endif() 0221 0222 set_property(SOURCE ${_file} PROPERTY ${_ECM_QMLMODULE_PROPERTY_VERSION} "${ARG_VERSION}") 0223 if (ARG_PRIVATE) 0224 set_property(SOURCE ${_file} PROPERTY ${_ECM_QMLMODULE_PROPERTY_PRIVATE} TRUE) 0225 endif() 0226 set_property(SOURCE ${_file} PROPERTY ${_ECM_QMLMODULE_PROPERTY_PATH} "${ARG_PATH}") 0227 set_property(TARGET ${ARG_TARGET} 0228 APPEND PROPERTY ${_ECM_QMLMODULE_PROPERTY_FILES} ${_path} 0229 ) 0230 endforeach() 0231 endfunction() 0232 0233 function(ecm_finalize_qml_module ARG_TARGET) 0234 cmake_parse_arguments(PARSE_ARGV 1 ARG "" "DESTINATION" "") 0235 0236 _ecm_qmlmodule_verify_qml_target(${ARG_TARGET}) 0237 0238 if (NOT ARG_DESTINATION) 0239 set(ARG_DESTINATION "${KDE_INSTALL_QMLDIR}") 0240 endif() 0241 if ("${ARG_DESTINATION}" STREQUAL "") 0242 message(FATAL_ERROR "ecm_finalize_qml_module called without argument DESTINATION and KDE_INSTALL_QMLDIR is not set") 0243 endif() 0244 0245 get_target_property(_qml_uri ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_URI}) 0246 get_target_property(_version ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_VERSION}) 0247 0248 _ecm_qmlmodule_generate_qmldir(${ARG_TARGET}) 0249 _ecm_qmlmodule_uri_to_path(_plugin_path "${_qml_uri}" "${_version}") 0250 0251 get_target_property(_qml_only ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_QMLONLY}) 0252 0253 if (NOT BUILD_SHARED_LIBS) 0254 _ecm_qmlmodule_generate_qrc(${ARG_TARGET}) 0255 set(CPP_RESOURCE_INIT "#include <qglobal.h> \n#include <QDebug> \n void initQmlResource${ARG_TARGET}() {Q_INIT_RESOURCE(${ARG_TARGET}); qWarning()<<Q_FUNC_INFO;};") 0256 file(WRITE ${ARG_TARGET}_init.cpp "${CPP_RESOURCE_INIT}") 0257 target_sources(${ARG_TARGET} PRIVATE ${ARG_TARGET}_init.cpp) 0258 target_compile_definitions(${ARG_TARGET} PRIVATE -DQT_PLUGIN_RESOURCE_INIT_FUNCTION=initQmlResource${ARG_TARGET} -DQT_STATICPLUGIN=1) 0259 0260 if (${_qml_only}) 0261 # If we do not have any C++ sources for the target, we need a way to 0262 # compile the generated QRC file. So generate a very plain C++ QML 0263 # plugin that we include in the target. 0264 configure_file(${_ECM_QMLMODULE_STATIC_QMLONLY_H} ${CMAKE_CURRENT_BINARY_DIR}/QmlModule.h @ONLY) 0265 configure_file(${_ECM_QMLMODULE_STATIC_QMLONLY_CPP} ${CMAKE_CURRENT_BINARY_DIR}/QmlModule.cpp @ONLY) 0266 0267 target_sources(${ARG_TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/QmlModule.cpp) 0268 if (TARGET Qt::Qml) 0269 target_link_libraries(${ARG_TARGET} PRIVATE Qt::Qml) 0270 else() 0271 target_link_libraries(${ARG_TARGET} PRIVATE Qt5::Qml) 0272 endif() 0273 endif() 0274 0275 install(TARGETS ${ARG_TARGET} DESTINATION ${ARG_DESTINATION}/${_plugin_path}) 0276 0277 return() 0278 endif() 0279 0280 get_target_property(_runtime_output_dir ${ARG_TARGET} RUNTIME_OUTPUT_DIRECTORY) 0281 if (NOT ${_runtime_output_dir}) 0282 if ("${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" STREQUAL "") 0283 set(_runtime_output_dir ${CMAKE_CURRENT_BINARY_DIR}) 0284 else() 0285 set(_runtime_output_dir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY}) 0286 endif() 0287 endif() 0288 0289 add_custom_command( 0290 TARGET ${ARG_TARGET} 0291 POST_BUILD 0292 WORKING_DIRECTORY ${CMAKE_BINARY_DIR} 0293 COMMAND ${CMAKE_COMMAND} -E make_directory ${_runtime_output_dir}/${_plugin_path} 0294 BYPRODUCTS ${_runtime_output_dir}/${_plugin_path} 0295 ) 0296 0297 get_target_property(_qmldir_file ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_QMLDIR}) 0298 install(FILES ${_qmldir_file} DESTINATION ${ARG_DESTINATION}/${_plugin_path} RENAME "qmldir") 0299 0300 add_custom_command( 0301 TARGET ${ARG_TARGET} 0302 POST_BUILD 0303 WORKING_DIRECTORY ${_runtime_output_dir} 0304 COMMAND ${CMAKE_COMMAND} -E copy ${_qmldir_file} ${_plugin_path}/qmldir 0305 ) 0306 0307 if (NOT ${_qml_only}) 0308 install(TARGETS ${ARG_TARGET} DESTINATION ${ARG_DESTINATION}/${_plugin_path}) 0309 0310 add_custom_command( 0311 TARGET ${ARG_TARGET} 0312 POST_BUILD 0313 WORKING_DIRECTORY ${_runtime_output_dir} 0314 COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${ARG_TARGET}> ${_plugin_path} 0315 ) 0316 endif() 0317 0318 get_target_property(_qml_files ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_FILES}) 0319 foreach(_file ${_qml_files}) 0320 get_filename_component(_filename ${_file} NAME) 0321 get_property(_path SOURCE ${_file} PROPERTY ${_ECM_QMLMODULE_PROPERTY_PATH}) 0322 0323 set(_file_path "${_plugin_path}/") 0324 if (NOT "${_path}" STREQUAL "") 0325 set(_file_path "${_plugin_path}/${_path}/") 0326 endif() 0327 0328 install(FILES ${_file} DESTINATION ${ARG_DESTINATION}/${_file_path}) 0329 0330 add_custom_command( 0331 TARGET ${ARG_TARGET} 0332 POST_BUILD 0333 WORKING_DIRECTORY ${_runtime_output_dir} 0334 COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_path} 0335 COMMAND ${CMAKE_COMMAND} -E copy ${_file} ${_file_path} 0336 BYPRODUCTS ${_file_path}/${_filename} 0337 ) 0338 endforeach() 0339 endfunction()