// Copyright (C) 2021 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
\page qt-query-qml-module.html
\ingroup cmake-commands-qtqml

\title qt_query_qml_module
\keyword qt6_query_qml_module

\summary {Retrieve information about a QML module.}

\include cmake-find-package-qml.qdocinc

\cmakecommandsince 6.3

\section1 Synopsis

\badcode
qt_query_qml_module(
    target
    [URI uri_var]
    [VERSION version_var]
    [PLUGIN_TARGET plugin_target_var]
    [TARGET_PATH target_path_var]
    [MODULE_RESOURCE_PATH module_resource_path_var]
    [QMLDIR qmldir_var]
    [TYPEINFO typeinfo_var]
    [QML_FILES qml_files_var]
    [QML_FILES_DEPLOY_PATHS qml_files_deploy_paths_var]
    [QML_FILES_PREFIX_OVERRIDES qml_files_prefix_overrides_var]
    [RESOURCES resources_var]
    [RESOURCES_DEPLOY_PATHS resources_deploy_paths_var]
    [RESOURCES_PREFIX_OVERRIDES resources_prefix_overrides_var]
)
\endcode

\versionlessCMakeCommandsNote qt6_query_qml_module()

\section1 Description

This command is used to obtain information about a QML module \c target.
That \c target must have previously been created by or passed to an earlier
call to \l{qt6_add_qml_module}{qt_add_qml_module()}. The \c target cannot be an
imported target.

The information provided by this command enables the caller to deploy all parts
of a single QML module. The project should install the \c target and the
associated plugin target (if the module has one and it is separate from the
backing \c target) using the standard \l{install(TARGETS)} command.
Everything else can be deployed with \l{install(FILES)}.

\section1 Arguments

Each of the optional arguments specifies the name of a variable in which to
store the corresponding QML module property.

\c URI and \c VERSION provide the module's uri and version respectively.

\c PLUGIN_TARGET can be used to obtain the name of the plugin target for the
QML module. Not all QML modules have a plugin, so the value returned for this
option could be an empty string. If the QML module has no separate backing
target, then \c target will be the same as the plugin target.

\c TARGET_PATH is the \c URI with dots (.) replaced by forward slashes (/).
It represents the path below the base QML module installation directory where
this QML module's \c{qmldir} file (and possibly others) should be deployed.
The QML module installation directory serves as a QML import path where
the QML engine will look for QML modules.
The default base QML module installation directory used by
\l{qt6_generate_deploy_qml_app_script}{qt_generate_deploy_qml_app_script()}
is \c{qml}. A project using a deployment script can use \l{QT_DEPLOY_QML_DIR}
rather than hard-coding this location (also see \l{QT_DEPLOY_PREFIX}).

\c MODULE_RESOURCE_PATH provides the resource path under which the QML module's
compiled-in files can be found. It is formed from
\l{qt6_add_qml_module}{qt_add_qml_module()}'s \c{RESOURCE_PREFIX} concatenated
with the module's \c TARGET_PATH.
The queried value should not be used for deployment, but may be helpful in
matching up resource paths with file system locations, if needed.

\c QMLDIR provides the path to the \c{qmldir} file. When deploying the QML
module, this file should be copied to the target path. In a deployment script,
this location can be obtained using \c{${QT_DEPLOY_PREFIX}/${QT_DEPLOY_QML_DIR}}.

\c TYPEINFO provides the path to the module's typeinfo file, if it has one.
It will be an empty string if the module has no typeinfo file. The typeinfo
file should be deployed to the same path as the \c{qmldir} file.

\c QML_FILES provides a list of all files added to the QML module through one
of the following methods:

\list
\li As \c{QML_FILES} arguments in \l{qt6_add_qml_module}{qt_add_qml_module()}.
\li As \c{FILES} arguments in \l{qt6_target_qml_sources}{qt_target_qml_sources()}.
\endlist

All files will be recorded with absolute paths.

\c QML_FILES_DEPLOY_PATHS provides a list with exactly the same number of
elements as \c QML_FILES. Each element of the \c QML_FILES_DEPLOY_PATHS list is
the path below the target path where the corresponding element of \c QML_FILES
should be deployed. The paths in \c QML_FILES_DEPLOY_PATHS include the file
name, since this could be different to the file name in \c QML_FILES due to the
use of resource aliases (see \l{QT_RESOURCE_ALIAS}).

Entries in \c QML_FILES_DEPLOY_PATHS can also be an empty string. Any file
added using \l{qt6_target_qml_sources}{qt_target_qml_sources()} with a custom
\c PREFIX will have no deploy path, since using a custom prefix typically means
the file sits outside of the QML module's target path.

\c QML_FILES_PREFIX_OVERRIDES provides another list with exactly the same
number of elements as \c QML_FILES. Where a file has been added with a custom
prefix as described in the preceding paragraph, its corresponding entry in the
\c QML_FILES_PREFIX_OVERRIDES list will contain the custom prefix used. For all
other files, their list entries will be an empty string.

\note As a special case, if there is only one file in the \c QML_FILES list,
then \c QML_FILES_DEPLOY_PATHS or \c QML_FILES_PREFIX_OVERRIDES may be an empty
string depending on whether that file has a custom prefix.
This is because CMake's way of representing lists and strings means that
it is impossible to distinguish between an empty string and a list with a single
empty element.

The \c RESOURCES, \c RESOURCES_DEPLOY_PATHS, and \c RESOURCES_PREFIX_OVERRIDES
options are analogous to those for \c QML_FILES discussed above.
\c RESOURCES provides a list of all files added to the QML module as
\c RESOURCES arguments to either \l{qt6_add_qml_module}{qt_add_qml_module()} or
\l{qt6_target_qml_sources}{qt_target_qml_sources()}. All paths will be
absolute. The meaning and usage of \c RESOURCES_DEPLOY_PATHS and
\c RESOURCES_PREFIX_OVERRIDES follows the same patterns as
\c QML_FILES_DEPLOY_PATHS and \c QML_FILES_PREFIX_OVERRIDES respectively.

\section1 Example

\badcode
cmake_minimum_required(VERSION 3.16...3.22)
project(MyThings)

find_package(Qt6 6.3 REQUIRED COMPONENTS Core Qml)

set(module_name "MyThings")
qt_add_qml_module(${module_name}
    URI My.Things
    VERSION 1.3
    RESOURCE_PREFIX org.mycompany/imports
    QML_FILES
        First.qml
        Second.qml
    RESOURCES
        Third.txt
)

qt_query_qml_module(${module_name}
    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
    QML_FILES_DEPLOY_PATHS qml_files_deploy_paths
    RESOURCES module_resources
    RESOURCES_DEPLOY_PATHS resources_deploy_paths
)

message("My QML module URI is: ${module_uri}")
message("My QML module version is: ${module_version}")

# Install the QML module backing library
set(staging_prefix "staging")
install(TARGETS ${module_name}
    ARCHIVE DESTINATION "${staging_prefix}/${CMAKE_INSTALL_LIBDIR}"
    LIBRARY DESTINATION "${staging_prefix}/${CMAKE_INSTALL_LIBDIR}"
    RUNTIME DESTINATION "${staging_prefix}/${CMAKE_INSTALL_BINDIR}"
)
set(module_dir "${staging_prefix}/qml/${module_target_path}")

# Install the QML module runtime loadable plugin
install(TARGETS "${module_plugin_target}"
    LIBRARY DESTINATION "${module_dir}"
    RUNTIME DESTINATION "${module_dir}"
)

# 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.
list(LENGTH module_qml_files num_files)
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()

# Install resources, possibly renamed.
list(LENGTH module_resources num_files)
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()

\endcode

*/
