Files
RedBear-OS/local/recipes/kde/kf6-extra-cmake-modules/source/modules/ECMQmlModule5.cmake
T
vasilito e0590a0b56 kde/kf6-extra-cmake-modules: rebase to 6.28.0 (ECM) + teach version parser set(VERSION)
kf6-kcoreaddons 6.28.0 requires ECM >= 6.28.0 but the vendored ECM source/ was
still 6.10.0: the sync engine skipped it because ECM's version marker is a bare
set(VERSION "X.Y.Z") that the parser didn't recognize (only KF_VERSION /
PROJECT_VERSION / RELEASE_SERVICE_VERSION). Re-lay ECM from its 6.28.0 source.tar
(pure cmake modules, no Redox port) and teach both the sync engine and the
validator to read set(VERSION) so this class is caught, not silently skipped.
2026-08-01 08:07:00 +03:00

342 lines
14 KiB
CMake

#
# SPDX-FileCopyrightText: 2021 Arjen Hiemstra <ahiemstra@heimr.nl>
#
# SPDX-License-Identifier: BSD-3-Clause
# Qt 5 implementation of ECMQmlModule
cmake_policy(VERSION 3.16)
set(_ECM_QMLMODULE_STATIC_QMLONLY_H "${CMAKE_CURRENT_LIST_DIR}/ECMQmlModule.h.in")
set(_ECM_QMLMODULE_STATIC_QMLONLY_CPP "${CMAKE_CURRENT_LIST_DIR}/ECMQmlModule.cpp.in")
set(_ECM_QMLMODULE_PROPERTY_URI "_ecm_qml_uri")
set(_ECM_QMLMODULE_PROPERTY_QMLDIR "_ecm_qmldir_file")
set(_ECM_QMLMODULE_PROPERTY_FILES "_ecm_qml_files")
set(_ECM_QMLMODULE_PROPERTY_QMLONLY "_ecm_qml_only")
set(_ECM_QMLMODULE_PROPERTY_VERSION "_ecm_qml_version")
set(_ECM_QMLMODULE_PROPERTY_PRIVATE "_ecm_qml_private")
set(_ECM_QMLMODULE_PROPERTY_PATH "_ecm_qml_path")
set(_ECM_QMLMODULE_PROPERTY_CLASSNAME "_ecm_qml_classname")
set(_ECM_QMLMODULE_PROPERTY_DEPENDS "_ecm_qml_depends")
macro(_ecm_qmlmodule_verify_qml_target ARG_TARGET)
if (NOT TARGET ${ARG_TARGET})
message(FATAL_ERROR "Target ${ARG_TARGET} does not exist")
endif()
get_target_property(_qml_uri ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_URI})
if ("${_qml_uri}" STREQUAL "" OR "${_qml_uri}" STREQUAL "${_ECM_QMLMODULE_PROPERTY_URI}-NOTFOUND")
message(FATAL_ERROR "Target ${ARG_TARGET} is not a QML plugin target")
endif()
endmacro()
function(_ecm_qmlmodule_generate_qmldir ARG_TARGET)
get_target_property(_qml_uri ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_URI})
get_target_property(_qml_files ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_FILES})
get_target_property(_qml_only ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_QMLONLY})
get_target_property(_qml_classname ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_CLASSNAME})
set(_qmldir_template "# This file was automatically generated by ECMQmlModule and should not be modified")
string(APPEND _qmldir_template "\nmodule ${_qml_uri}")
if (NOT ${_qml_only})
string(APPEND _qmldir_template "\nplugin ${ARG_TARGET}")
if ("${_qml_classname}" STREQUAL "")
string(APPEND _qmldir_template "\nclassname ${ARG_TARGET}")
else()
string(APPEND _qmldir_template "\nclassname ${_qml_classname}")
endif()
endif()
get_target_property(_qml_depends ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_DEPENDS})
if (NOT "${_qml_depends}" STREQUAL "")
foreach(_depends ${_qml_depends})
string(APPEND _qmldir_template "\ndepends ${_depends}")
endforeach()
endif()
foreach(_file ${_qml_files})
get_filename_component(_filename ${_file} NAME)
get_filename_component(_classname ${_file} NAME_WE)
get_property(_version SOURCE ${_file} PROPERTY ${_ECM_QMLMODULE_PROPERTY_VERSION})
get_property(_private SOURCE ${_file} PROPERTY ${_ECM_QMLMODULE_PROPERTY_PRIVATE})
get_property(_singleton SOURCE ${_file} PROPERTY "QT_QML_SINGLETON_TYPE")
get_property(_path SOURCE ${_file} PROPERTY ${_ECM_QMLMODULE_PROPERTY_PATH})
cmake_path(SET _actual_path "${_path}")
cmake_path(APPEND _actual_path "${_filename}")
if (_singleton)
string(APPEND _qmldir_template "\nsingleton ${_classname} ${_version} ${_actual_path}")
else()
if (NOT _private)
string(APPEND _qmldir_template "\n${_classname} ${_version} ${_actual_path}")
else()
string(APPEND _qmldir_template "\ninternal ${_classname} ${_actual_path}")
endif()
endif()
endforeach()
get_target_property(_qml_version ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_VERSION})
string(APPEND _qmldir_template "\n# KDE-qmldir-Version: ${_qml_version}")
string(APPEND _qmldir_template "\n")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${ARG_TARGET}_qmldir" "${_qmldir_template}")
set_target_properties(${ARG_TARGET} PROPERTIES _ecm_qmldir_file "${CMAKE_CURRENT_BINARY_DIR}/${ARG_TARGET}_qmldir")
endfunction()
function(_ecm_qmlmodule_generate_qrc ARG_TARGET)
get_target_property(_qml_uri ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_URI})
get_target_property(_qml_files ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_FILES})
get_target_property(_qmldir_file ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_QMLDIR})
get_target_property(_qml_version ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_VERSION})
_ecm_qmlmodule_uri_to_path(_qml_prefix "${_qml_uri}" "${_qml_version}")
set(_qrc_template "<!-- This file was automatically generated by ECMQmlModule and should not be modified -->")
string(APPEND _qrc_template "\n<RCC>\n<qresource prefix=\"/qt-project.org/imports/${_qml_prefix}\">")
string(APPEND _qrc_template "\n<file alias=\"qmldir\">${_qmldir_file}</file>")
foreach(_file ${_qml_files})
get_filename_component(_filename ${_file} NAME)
get_property(_path SOURCE ${_file} PROPERTY ${_ECM_QMLMODULE_PROPERTY_PATH})
set(_file_path "${_filename}")
if (NOT "${_path}" STREQUAL "")
set(_file_path "${_path}/${_filename}")
endif()
string(APPEND _qrc_template "\n<file alias=\"${_file_path}\">${_file}</file>")
endforeach()
string(APPEND _qrc_template "\n</qresource>\n</RCC>\n")
file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${ARG_TARGET}.qrc" "${_qrc_template}")
qt_add_resources(_qrc_output "${CMAKE_CURRENT_BINARY_DIR}/${ARG_TARGET}.qrc")
target_sources(${ARG_TARGET} PRIVATE ${_qrc_output})
endfunction()
function(ecm_add_qml_module ARG_TARGET)
cmake_parse_arguments(PARSE_ARGV 1 ARG "NO_PLUGIN" "URI;VERSION;CLASSNAME" "")
if ("${ARG_TARGET}" STREQUAL "")
message(FATAL_ERROR "ecm_add_qml_module called without a valid target name.")
endif()
if ("${ARG_URI}" STREQUAL "")
message(FATAL_ERROR "ecm_add_qml_module called without a valid module URI.")
endif()
string(FIND "${ARG_URI}" " " "_space")
if (${_space} GREATER_EQUAL 0)
message(FATAL_ERROR "ecm_add_qml_module called without a valid module URI.")
endif()
if (${BUILD_SHARED_LIBS} AND ${ARG_NO_PLUGIN})
# CMake doesn't like library targets without sources, so if we have no
# C++ sources, use a plain target that we can add all the install stuff
# to.
add_custom_target(${ARG_TARGET} ALL)
else()
add_library(${ARG_TARGET})
endif()
if (NOT ARG_VERSION)
set(ARG_VERSION "1.0")
endif()
set_target_properties(${ARG_TARGET} PROPERTIES
${_ECM_QMLMODULE_PROPERTY_URI} "${ARG_URI}"
${_ECM_QMLMODULE_PROPERTY_FILES} ""
${_ECM_QMLMODULE_PROPERTY_QMLONLY} "${ARG_NO_PLUGIN}"
${_ECM_QMLMODULE_PROPERTY_VERSION} "${ARG_VERSION}"
${_ECM_QMLMODULE_PROPERTY_CLASSNAME} "${ARG_CLASSNAME}"
${_ECM_QMLMODULE_PROPERTY_DEPENDS} ""
)
# QQmlImportDatabase::resolvePlugin doesn't accept lib prefixes under
# Windows, causing to fail to import when using as a dynamic plugin.
if (MINGW)
set_target_properties(${ARG_TARGET} PROPERTIES PREFIX "")
endif()
# -Muri is required for static QML plugins to work properly, see
# https://bugreports.qt.io/browse/QTBUG-82598
set_target_properties(${ARG_TARGET} PROPERTIES AUTOMOC_MOC_OPTIONS -Muri=${ARG_URI})
endfunction()
function(ecm_add_qml_module_dependencies ARG_TARGET)
cmake_parse_arguments(PARSE_ARGV 1 ARG "" "" "DEPENDS")
_ecm_qmlmodule_verify_qml_target(${ARG_TARGET})
if ("${ARG_DEPENDS}" STREQUAL "")
message(FATAL_ERROR "ecm_add_qml_module_dependencies called without required argument DEPENDS")
endif()
set_target_properties(${ARG_TARGET} PROPERTIES ${_ECM_QMLMODULE_PROPERTY_DEPENDS} "${ARG_DEPENDS}")
endfunction()
function(ecm_target_qml_sources ARG_TARGET)
cmake_parse_arguments(PARSE_ARGV 1 ARG "PRIVATE" "VERSION;PATH" "SOURCES")
_ecm_qmlmodule_verify_qml_target(${ARG_TARGET})
if ("${ARG_SOURCES}" STREQUAL "")
message(FATAL_ERROR "ecm_target_qml_sources called without required argument SOURCES")
endif()
if ("${ARG_VERSION}" STREQUAL "")
get_target_property(ARG_VERSION ${ARG_TARGET} "_ecm_qml_version")
endif()
# In case we have not specified a version in add_qml_module, we use 1.0 as a default for the individual QML files
if (NOT ARG_VERSION)
set(ARG_VERSION "1.0")
endif()
foreach(_file ${ARG_SOURCES})
# Check if a given file exists, but only for files that are not
# automatically generated.
set(_path "${_file}")
get_source_file_property(_generated ${_file} GENERATED)
if (NOT _generated)
if (IS_ABSOLUTE ${_path})
# Assume absolute paths are generated, which may not always be
# true but is fairly likely.
set(_generated TRUE)
else()
string(FIND ${_file} ${CMAKE_BINARY_DIR} _in_binary_dir)
if (${_in_binary_dir} GREATER_EQUAL 0)
# Assume anything in binary dir is generated.
set(_generated TRUE)
else()
set(_path "${CMAKE_CURRENT_SOURCE_DIR}/${_file}")
endif()
endif()
endif()
if (NOT ${_generated} AND NOT EXISTS ${_path})
message(FATAL_ERROR "ecm_target_qml_sources called with nonexistent file ${_file}")
endif()
set_property(SOURCE ${_file} PROPERTY ${_ECM_QMLMODULE_PROPERTY_VERSION} "${ARG_VERSION}")
if (ARG_PRIVATE)
set_property(SOURCE ${_file} PROPERTY ${_ECM_QMLMODULE_PROPERTY_PRIVATE} TRUE)
endif()
set_property(SOURCE ${_file} PROPERTY ${_ECM_QMLMODULE_PROPERTY_PATH} "${ARG_PATH}")
set_property(TARGET ${ARG_TARGET}
APPEND PROPERTY ${_ECM_QMLMODULE_PROPERTY_FILES} ${_path}
)
endforeach()
endfunction()
function(ecm_finalize_qml_module ARG_TARGET)
cmake_parse_arguments(PARSE_ARGV 1 ARG "" "DESTINATION" "")
_ecm_qmlmodule_verify_qml_target(${ARG_TARGET})
if (NOT ARG_DESTINATION)
set(ARG_DESTINATION "${KDE_INSTALL_QMLDIR}")
endif()
if ("${ARG_DESTINATION}" STREQUAL "")
message(FATAL_ERROR "ecm_finalize_qml_module called without argument DESTINATION and KDE_INSTALL_QMLDIR is not set")
endif()
get_target_property(_qml_uri ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_URI})
get_target_property(_version ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_VERSION})
_ecm_qmlmodule_generate_qmldir(${ARG_TARGET})
_ecm_qmlmodule_uri_to_path(_plugin_path "${_qml_uri}" "${_version}")
get_target_property(_qml_only ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_QMLONLY})
if (NOT BUILD_SHARED_LIBS)
_ecm_qmlmodule_generate_qrc(${ARG_TARGET})
set(CPP_RESOURCE_INIT "#include <qglobal.h> \n#include <QDebug> \n void initQmlResource${ARG_TARGET}() {Q_INIT_RESOURCE(${ARG_TARGET}); qWarning()<<Q_FUNC_INFO;};")
file(WRITE ${ARG_TARGET}_init.cpp "${CPP_RESOURCE_INIT}")
target_sources(${ARG_TARGET} PRIVATE ${ARG_TARGET}_init.cpp)
target_compile_definitions(${ARG_TARGET} PRIVATE -DQT_PLUGIN_RESOURCE_INIT_FUNCTION=initQmlResource${ARG_TARGET} -DQT_STATICPLUGIN=1)
if (${_qml_only})
# If we do not have any C++ sources for the target, we need a way to
# compile the generated QRC file. So generate a very plain C++ QML
# plugin that we include in the target.
configure_file(${_ECM_QMLMODULE_STATIC_QMLONLY_H} ${CMAKE_CURRENT_BINARY_DIR}/QmlModule.h @ONLY)
configure_file(${_ECM_QMLMODULE_STATIC_QMLONLY_CPP} ${CMAKE_CURRENT_BINARY_DIR}/QmlModule.cpp @ONLY)
target_sources(${ARG_TARGET} PRIVATE ${CMAKE_CURRENT_BINARY_DIR}/QmlModule.cpp)
if (TARGET Qt::Qml)
target_link_libraries(${ARG_TARGET} PRIVATE Qt::Qml)
else()
target_link_libraries(${ARG_TARGET} PRIVATE Qt5::Qml)
endif()
endif()
install(TARGETS ${ARG_TARGET} DESTINATION ${ARG_DESTINATION}/${_plugin_path})
return()
endif()
get_target_property(_runtime_output_dir ${ARG_TARGET} RUNTIME_OUTPUT_DIRECTORY)
if (NOT ${_runtime_output_dir})
if ("${CMAKE_RUNTIME_OUTPUT_DIRECTORY}" STREQUAL "")
set(_runtime_output_dir ${CMAKE_CURRENT_BINARY_DIR})
else()
set(_runtime_output_dir ${CMAKE_RUNTIME_OUTPUT_DIRECTORY})
endif()
endif()
add_custom_command(
TARGET ${ARG_TARGET}
POST_BUILD
WORKING_DIRECTORY ${CMAKE_BINARY_DIR}
COMMAND ${CMAKE_COMMAND} -E make_directory ${_runtime_output_dir}/${_plugin_path}
BYPRODUCTS ${_runtime_output_dir}/${_plugin_path}
)
get_target_property(_qmldir_file ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_QMLDIR})
install(FILES ${_qmldir_file} DESTINATION ${ARG_DESTINATION}/${_plugin_path} RENAME "qmldir")
add_custom_command(
TARGET ${ARG_TARGET}
POST_BUILD
WORKING_DIRECTORY ${_runtime_output_dir}
COMMAND ${CMAKE_COMMAND} -E copy ${_qmldir_file} ${_plugin_path}/qmldir
)
if (NOT ${_qml_only})
install(TARGETS ${ARG_TARGET} DESTINATION ${ARG_DESTINATION}/${_plugin_path})
add_custom_command(
TARGET ${ARG_TARGET}
POST_BUILD
WORKING_DIRECTORY ${_runtime_output_dir}
COMMAND ${CMAKE_COMMAND} -E copy $<TARGET_FILE:${ARG_TARGET}> ${_plugin_path}
)
endif()
get_target_property(_qml_files ${ARG_TARGET} ${_ECM_QMLMODULE_PROPERTY_FILES})
foreach(_file ${_qml_files})
get_filename_component(_filename ${_file} NAME)
get_property(_path SOURCE ${_file} PROPERTY ${_ECM_QMLMODULE_PROPERTY_PATH})
set(_file_path "${_plugin_path}/")
if (NOT "${_path}" STREQUAL "")
set(_file_path "${_plugin_path}/${_path}/")
endif()
install(FILES ${_file} DESTINATION ${ARG_DESTINATION}/${_file_path})
add_custom_command(
TARGET ${ARG_TARGET}
POST_BUILD
WORKING_DIRECTORY ${_runtime_output_dir}
COMMAND ${CMAKE_COMMAND} -E make_directory ${_file_path}
COMMAND ${CMAKE_COMMAND} -E copy ${_file} ${_file_path}
BYPRODUCTS ${_runtime_output_dir}/${_file_path}/${_filename}
)
endforeach()
endfunction()