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()