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

/*!
\page qt-generate-deploy-qml-app-script.html
\ingroup cmake-commands-qtqml

\title qt_generate_deploy_qml_app_script
\keyword qt6_generate_deploy_qml_app_script

\summary {Generate a deployment script for a QML application.}

\include cmake-find-package-qml.qdocinc

\cmakecommandsince 6.3

\include cmake-qml-qt-finalize-target-warning.qdocinc warning

\section1 Synopsis

\badcode
qt_generate_deploy_qml_app_script(
    TARGET <target>
    OUTPUT_SCRIPT <var>
    [NO_UNSUPPORTED_PLATFORM_ERROR]
    [NO_TRANSLATIONS]
    [NO_COMPILER_RUNTIME]
    [NO_PLUGINS]                                  # since Qt 6.10
    [EXCLUDE_PLUGIN_TYPES type_or_target...]      # since Qt 6.10
    [INCLUDE_PLUGIN_TYPES type_or_target...]      # since Qt 6.10
    [EXCLUDE_PLUGINS name...]                     # since Qt 6.10
    [INCLUDE_PLUGINS name...]                     # since Qt 6.10
    [DEPLOY_TOOL_OPTIONS ...]
    [DEPLOY_USER_QML_MODULES_ON_UNSUPPORTED_PLATFORM]
    [MACOS_BUNDLE_POST_BUILD]
    [PRE_INCLUDE_REGEXES regexes...]
    [PRE_EXCLUDE_REGEXES regexes...]
    [POST_INCLUDE_REGEXES regexes...]
    [POST_EXCLUDE_REGEXES regexes...]
    [POST_INCLUDE_FILES files...]
    [POST_EXCLUDE_FILES files...]
)
\endcode

\versionlessCMakeCommandsNote qt6_generate_deploy_qml_app_script()

\section1 Description

Installing an executable target that is also a QML module requires deploying
a number of things in addition to the target itself. Qt libraries and other
libraries from the project, Qt plugins, and the runtime parts of all QML modules
the application uses may all need to be installed too. The installed layout
is also going to be different for macOS app bundles compared to other platforms.
The \c{qt_generate_deploy_qml_app_script()} is a convenience command intended
to simplify that process, similar to what
\l{qt6_generate_deploy_app_script}{qt_generate_deploy_app_script()} does for
non-QML applications.

The command expects the application to follow Qt's recommended install
directory structure fairly closely. That structure is based on CMake's default
install layout, as determined by \l{GNUInstallDirs} (except for macOS app
bundles, which follow Apple's requirements instead). QML modules are installed
to the appropriate location for the platform. For macOS bundles, each QML
module's \c{qmldir} file is installed under the appropriate subdirectory below
\c{Resources/qml} and the module's plugin (if present) is installed under
\c{PlugIns}. The app bundle is assumed to be installed directly to the base
installation location (see the \l{Example} further below). For all other platforms,
both the \c{qmldir} and the module's plugin are installed under the appropriate
subdirectory below \c{qml}, which itself is relative to the base installation
location.

\c{qt_generate_deploy_qml_app_script()} generates a script whose name will be
stored in the variable named by the \c{OUTPUT_SCRIPT} option. That script
is only written at CMake generate-time. It is intended to be used with the
\l{install(SCRIPT)} command, which should come after the application's target
has been installed using \l{install(TARGETS)}.

The deployment script will call
\l{qt6_deploy_qml_imports}{qt_deploy_qml_imports()} with a suitable set of
options for the standard install layout. For macOS app bundles and Windows
targets, it will then also call
\l{qt6_deploy_runtime_dependencies}{qt_deploy_runtime_dependencies()}, again
with suitable options for the standard install layout.

Calling \c{qt_generate_deploy_qml_app_script()} for a platform that is not
supported by \c{qt_deploy_runtime_dependencies} will result in a fatal error,
unless the \c{NO_UNSUPPORTED_PLATFORM_ERROR} option is given. When the option
is given and the project is built for an unsupported platform, neither QML modules
nor regular runtime dependencies will be installed.
To ensure that the QML modules are still installed, specify both the
\c{NO_UNSUPPORTED_PLATFORM_ERROR} and
\c{DEPLOY_USER_QML_MODULES_ON_UNSUPPORTED_PLATFORM} options.
The latter option will ensure that QML modules built as part of the project
are still installed.

The \c{MACOS_BUNDLE_POST_BUILD} option enables an extra step when \c{target}
is a macOS app bundle. A post-build rule will be created which uses the
deployment script to deploy enough of the imported QML modules to allow the
application to run directly from the build directory (essentially just the
\c{qmldir} files and symlinks to plugins). This is usually desirable to support
development of the application. \c{MACOS_BUNDLE_POST_BUILD} is ignored for all
other platforms.

On platforms other than macOS, Qt translations are automatically deployed. To
inhibit this behavior, specify \c{NO_TRANSLATIONS}. Use
\l{qt_deploy_translations}{qt_deploy_translations()} to deploy translations in a
customized way.

For Windows desktop applications, the required runtime files for the compiler
are also installed by default. To prevent this, specify \c{NO_COMPILER_RUNTIME}.

Since Qt 6.7, you can use \c{DEPLOY_TOOL_OPTIONS} to pass additional options to
the underlying deployment tool. This only has an effect if the underlying
deployment tool is either macdeployqt or windeployqt.

The options \c{PRE_INCLUDE_REGEXES}, \c{PRE_EXCLUDE_REGEXES},
\c{POST_INCLUDE_REGEXES}, \c{POST_EXCLUDE_REGEXES}, \c{POST_INCLUDE_FILES}, and
\c{POST_EXCLUDE_FILES} can be specified to control the deployment of runtime
dependencies. These options do not apply to all platforms and are forwarded
unmodified to
\l{qt6_deploy_runtime_dependencies}{qt_deploy_runtime_dependencies()}.

The options \c EXCLUDE_PLUGINS, \c EXCLUDE_PLUGIN_TYPES, \c INCLUDE_PLUGINS, and
\c INCLUDE_PLUGIN_TYPES are used to select Qt plugins. See
\l{qt6_deploy_runtime_dependencies}{qt_deploy_runtime_dependencies()} for their
documentation.

You can turn off plugin deployment altogether with the \c NO_PLUGINS option.

For deploying a non-QML application, use
\l{qt6_generate_deploy_app_script}{qt_generate_deploy_app_script()}
instead. It is an error to call both \c{qt_generate_deploy_qml_app_script()}
and \l{qt6_generate_deploy_app_script}{qt_generate_deploy_app_script()} for the
same target.

\sa {qt6_standard_project_setup}{qt_standard_project_setup()},
    {qt6_generate_deploy_app_script}{qt_generate_deploy_app_script()}

\section1 Example

The following example shows how to deploy a QtQuick app.

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

find_package(Qt6 6.3 REQUIRED COMPONENTS Core Qml)
qt_standard_project_setup()

qt_add_executable(MyApp main.cpp)
qt_add_qml_module(MyApp
    URI Application
    VERSION 1.0
    QML_FILES main.qml MyThing.qml
)

install(TARGETS MyApp
    BUNDLE  DESTINATION .
    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
)

qt_generate_deploy_qml_app_script(
    TARGET MyApp
    OUTPUT_SCRIPT deploy_script
    MACOS_BUNDLE_POST_BUILD
    NO_UNSUPPORTED_PLATFORM_ERROR
    DEPLOY_USER_QML_MODULES_ON_UNSUPPORTED_PLATFORM
)
install(SCRIPT ${deploy_script})
\endcode

The following example shows how to pass additional options to the underlying
deployment tool.

\badcode
set(deploy_tool_options_arg "")
if(APPLE)
    set(deploy_tool_options_arg --hardened-runtime)
elseif(WIN32)
    set(deploy_tool_options_arg --no-compiler-runtime)
endif()

qt_generate_deploy_qml_app_script(
    ...
    DEPLOY_TOOL_OPTIONS ${deploy_tool_options_arg}
)
install(SCRIPT ${deploy_script})
\endcode
*/
