Files
RedBear-OS/local/recipes/kde/kf6-extra-cmake-modules/source/modules/ECMQmlModule6.cmake
T
2026-04-14 10:51:06 +01:00

259 lines
9.8 KiB
CMake

#
# SPDX-FileCopyrightText: 2023 Arjen Hiemstra <ahiemstra@heimr.nl>
#
# SPDX-License-Identifier: BSD-3-Clause
# Qt 6 implementation of ECMQmlModule
set(QT_NO_CREATE_VERSIONLESS_FUNCTIONS ON)
find_package(Qt6 COMPONENTS Core Qml CONFIG)
unset(QT_NO_CREATE_VERSIONLESS_FUNCTIONS)
if (NOT TARGET Qt6::Qml)
message(WARNING "Target Qt6::Qml was not found. ECMQmlModule requires the QML module when building with Qt 6")
return()
endif()
# Match KDECMakeSettings' RUNTIME_OUTPUT_DIRECTORY so that we can load plugins from
# the build directory when running tests. But only if we don't yet have an output directory.
if (NOT QT_QML_OUTPUT_DIRECTORY)
set(QT_QML_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/bin")
endif()
# Stop warning about a changed import prefix.
qt6_policy(SET QTP0001 NEW)
function(ecm_add_qml_module ARG_TARGET)
cmake_parse_arguments(PARSE_ARGV 1 ARG "NO_PLUGIN;QT_NO_PLUGIN;GENERATE_PLUGIN_SOURCE" "URI;VERSION;CLASSNAME;OUTPUT_TARGETS" "")
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()
set(_arguments ${ARG_TARGET} URI ${ARG_URI})
if (ARG_VERSION)
list(APPEND _arguments VERSION ${ARG_VERSION})
endif()
if (ARG_CLASSNAME)
message(AUTHOR_WARNING "The CLASSNAME argument to ecm_add_qml_module is deprecated for Qt 6; Use CLASS_NAME instead.")
list(APPEND _arguments CLASS_NAME ${ARG_CLASSNAME})
endif()
if (ARG_NO_PLUGIN)
message(AUTHOR_WARNING "The NO_PLUGIN argument to ecm_add_qml_module is deprecated for Qt 6; For Qt 6 QML modules always require a plugin library. Use GENERATE_PLUGIN_SOURCE instead. If you wish to use the NO_PLUGIN feature from qt_add_qml_module, use QT_NO_PLUGIN.")
set(ARG_GENERATE_PLUGIN_SOURCE TRUE)
endif()
if (ARG_QT_NO_PLUGIN)
list(APPEND _arguments NO_PLUGIN)
endif()
if (NOT ARG_GENERATE_PLUGIN_SOURCE)
list(APPEND _arguments NO_GENERATE_PLUGIN_SOURCE)
endif()
if (NOT TARGET ${ARG_TARGET})
list(APPEND _arguments PLUGIN_TARGET ${ARG_TARGET})
if (BUILD_SHARED_LIBS)
list(APPEND _arguments SHARED)
else()
list(APPEND _arguments STATIC)
endif()
endif()
# make qmlimportscanner also find QML modules installed
# outside of the Qt prefix
if(IS_DIRECTORY "${CMAKE_INSTALL_PREFIX}/${KDE_INSTALL_QMLDIR}")
list(APPEND _import_paths "${CMAKE_INSTALL_PREFIX}/${KDE_INSTALL_QMLDIR}")
endif()
foreach(_prefix ${CMAKE_PREFIX_PATH})
if(IS_DIRECTORY "${_prefix}/${KDE_INSTALL_QMLDIR}")
list(APPEND _import_paths "${_prefix}/${KDE_INSTALL_QMLDIR}")
endif()
endforeach()
list(APPEND _arguments IMPORT_PATH ${_import_paths})
list(APPEND _arguments ${ARG_UNPARSED_ARGUMENTS})
qt6_add_qml_module(${_arguments} OUTPUT_TARGETS _out_targets)
if (ARG_OUTPUT_TARGETS)
set(${ARG_OUTPUT_TARGETS} ${_out_targets} PARENT_SCOPE)
endif()
set_target_properties(${ARG_TARGET} PROPERTIES _ecm_output_targets "${_out_targets}")
# KDECMakeSettings sets the prefix of MODULE targets to empty but Qt will
# not load a QML plugin without prefix. So we need to force it here.
qt6_query_qml_module(${ARG_TARGET} PLUGIN_TARGET _plugin_target)
if (NOT WIN32 AND TARGET ${_plugin_target})
set_target_properties(${_plugin_target} PROPERTIES PREFIX "lib")
endif()
option(VERBOSE_QML_COMPILER "Enable verbose output for qmlcachegen" OFF)
if (VERBOSE_QML_COMPILER)
set_target_properties(${ARG_TARGET} PROPERTIES
QT_QMLCACHEGEN_ARGUMENTS "--verbose"
)
endif()
endfunction()
function(ecm_add_qml_module_dependencies ARG_TARGET)
message(AUTHOR_WARNING "ecm_add_qml_module_dependencies is deprecated for Qt 6; use the DEPENDENCIES argument to ecm_add_qml_module() instead.")
endfunction()
function(ecm_target_qml_sources ARG_TARGET)
cmake_parse_arguments(PARSE_ARGV 1 ARG "PRIVATE" "VERSION;PATH;OUTPUT_TARGETS" "SOURCES")
if ("${ARG_SOURCES}" STREQUAL "")
message(FATAL_ERROR "ecm_target_qml_sources called without required argument SOURCES")
endif()
if (ARG_VERSION)
set_source_files_properties(${ARG_SOURCES} PROPERTIES QT_QML_SOURCE_VERSIONS "${ARG_VERSION}")
endif()
if (ARG_PRIVATE)
set_source_files_properties(${ARG_SOURCES} PROPERTIES QT_QML_INTERNAL_TYPE TRUE)
endif()
set(_QML_FILES)
set(_RESOURCES)
foreach(_path ${ARG_SOURCES})
get_filename_component(_file "${_path}" NAME)
get_filename_component(_ext "${_path}" EXT)
set(_resource_alias "${_file}")
if (ARG_PATH)
set(_resource_alias "${ARG_PATH}/${_file}")
endif()
set_source_files_properties("${_path}" PROPERTIES QT_RESOURCE_ALIAS "${_resource_alias}")
if ("${_ext}" MATCHES "(.qml|.js|.mjs)")
list(APPEND _QML_FILES "${_path}")
else()
list(APPEND _RESOURCES "${_path}")
endif()
endforeach()
if(_QML_FILES)
qt6_target_qml_sources(${ARG_TARGET} QML_FILES ${_QML_FILES} OUTPUT_TARGETS _out_targets_qml ${ARG_UNPARSED_ARGUMENTS})
endif()
if(_RESOURCES)
qt6_target_qml_sources(${ARG_TARGET} RESOURCES ${_RESOURCES} OUTPUT_TARGETS _out_targets_qrc ${ARG_UNPARSED_ARGUMENTS})
endif()
list(APPEND _out_targets "${_out_targets_qml}" "${_out_targets_qrc}")
if (ARG_OUTPUT_TARGETS)
set(${ARG_OUTPUT_TARGETS} ${_out_targets} PARENT_SCOPE)
endif()
get_target_property(_ecm_output_targets ${ARG_TARGET} _ecm_output_targets)
list(APPEND _ecm_output_targets ${_out_targets})
set_target_properties(${ARG_TARGET} PROPERTIES _ecm_output_targets "${_ecm_output_targets}")
endfunction()
function(ecm_finalize_qml_module ARG_TARGET)
cmake_parse_arguments(PARSE_ARGV 1 ARG "" "DESTINATION;VERSION;EXPORT" "")
if (NOT ARG_DESTINATION)
set(ARG_DESTINATION "${KDE_INSTALL_QMLDIR}")
endif()
if ("${ARG_DESTINATION}" STREQUAL "")
message(FATAL_ERROR "ecm_finalize_qml_module called without required argument DESTINATION and KDE_INSTALL_QMLDIR is not set")
endif()
if (NOT ARG_VERSION)
set(ARG_VERSION "${PROJECT_VERSION}")
endif()
# This is effectively a workaround for missing upstream API, see QTBUG-100102
qt6_query_qml_module(${ARG_TARGET}
URI module_uri
VERSION module_version
PLUGIN_TARGET module_plugin_target
TARGET_PATH module_target_path
QMLDIR module_qmldir
TYPEINFO module_typeinfo
QML_FILES module_qml_files
RESOURCES module_resources
)
set(module_dir "${ARG_DESTINATION}/${module_target_path}")
if (NOT TARGET "${module_plugin_target}")
return()
endif()
if (ARG_EXPORT AND NOT BUILD_SHARED_LIBS)
set(_install_targets_args EXPORT "${ARG_EXPORT}")
endif()
install(TARGETS "${module_plugin_target}"
${_install_targets_args}
LIBRARY DESTINATION "${module_dir}"
RUNTIME DESTINATION "${module_dir}"
)
# Install dependent targets created for static builds
get_target_property(_ecm_output_targets ${ARG_TARGET} _ecm_output_targets)
if (_ecm_output_targets AND ARG_EXPORT)
install(TARGETS ${_ecm_output_targets}
EXPORT ${ARG_EXPORT}
LIBRARY DESTINATION "${module_dir}"
RUNTIME DESTINATION "${module_dir}"
OBJECTS DESTINATION "${module_dir}"
)
endif()
# Install the QML module meta information.
install(FILES "${module_qmldir}" DESTINATION "${module_dir}")
install(FILES "${module_typeinfo}" DESTINATION "${module_dir}")
# Install QML files, possibly renamed.
# see Kirigami::StyleSelector::resolveFileX, on Android we never use QML files from disk
# but rather always the ones from qrc
if (NOT ANDROID)
list(LENGTH module_qml_files num_files)
if (NOT "${module_qml_files}" MATCHES "NOTFOUND" AND ${num_files} GREATER 0)
qt6_query_qml_module(${ARG_TARGET} QML_FILES_DEPLOY_PATHS qml_files_deploy_paths)
math(EXPR last_index "${num_files} - 1")
foreach(i RANGE 0 ${last_index})
list(GET module_qml_files ${i} src_file)
list(GET qml_files_deploy_paths ${i} deploy_path)
get_filename_component(dst_name "${deploy_path}" NAME)
get_filename_component(dest_dir "${deploy_path}" DIRECTORY)
install(FILES "${src_file}" DESTINATION "${module_dir}/${dest_dir}" RENAME "${dst_name}")
endforeach()
endif()
endif()
# Install resources, possibly renamed.
list(LENGTH module_resources num_files)
if (NOT "${module_resources}" MATCHES "NOTFOUND" AND ${num_files} GREATER 0)
qt6_query_qml_module(${ARG_TARGET} RESOURCES_DEPLOY_PATHS resources_deploy_paths)
math(EXPR last_index "${num_files} - 1")
foreach(i RANGE 0 ${last_index})
list(GET module_resources ${i} src_file)
list(GET resources_deploy_paths ${i} deploy_path)
get_filename_component(dst_name "${deploy_path}" NAME)
get_filename_component(dest_dir "${deploy_path}" DIRECTORY)
install(FILES "${src_file}" DESTINATION "${module_dir}/${dest_dir}" RENAME "${dst_name}")
endforeach()
endif()
file(GENERATE OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/${ARG_TARGET}-kde-qmlmodule.version" CONTENT "${ARG_VERSION}\n")
install(FILES "${CMAKE_CURRENT_BINARY_DIR}/${ARG_TARGET}-kde-qmlmodule.version" DESTINATION "${module_dir}" RENAME "kde-qmlmodule.version")
endfunction()