// Copyright (C) 2020 The Qt Company Ltd
// Copyright (C) 2012 Klarälvdalens Datakonsult AB, a KDAB Group company, info@kdab.com, author Stephen Kelly <stephen.kelly@kdab.com>
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GFDL-1.3-no-invariants-only

/*!
    \page cmake-manual.html
    \target CMake Manual
    \title Build with CMake
    \brief Describes how to use CMake in your development projects.
    \nextpage Getting started with CMake

    \c{CMake} is a tool to simplify the build process for development projects across different
    platforms. \c CMake automatically generates build systems, such as Makefiles and Ninja
    files.

    \c{CMake} is a third-party tool with its own \l{CMake Documentation}{documentation}.
    This manual focuses on how to use \c{CMake} to build Qt applications and libraries.


    \section1 Table of Contents

    \list
        \li \l{Getting started with CMake}
        \list
            \li \l{Building a C++ console application}
            \li \l{Building a C++ GUI application}
            \li \l{Structuring projects}
            \li \l{Building libraries}
            \li \l{Using libraries}
            \li \l{Adding resources}
            \li \l{Adding translations}
            \li \l{Further reading}
        \endlist
        \li \l {Building a QML application}
        \li \l {Building a reusable QML module}
        \li \l{Building projects on the command line}
        \list
            \li \l{CMake generators}
            \li \l{qt-cmake}
            \li \l{Cross-compiling}
            \li \l{Specifying a custom toolchain file}
        \endlist
        \li \l{Imported targets}
        \li \l{Qt 5 and Qt 6 compatibility}
        \list
            \li \l{Versionless targets}
            \li \l{Versionless commands}
            \li \l{Supporting older Qt 5 versions}
            \li \l{Recommended practices}
        \endlist
        \li \l{CMake Command Reference}
        \list
            \li \l{cmake-commands-qtcore}{Qt6::Core}
            \li \l{cmake-commands-qtdbus}{Qt6::DBus}
            \li \l{cmake-macros-qtlinguisttools}{Qt6::LinguistTools}
            \li \l{cmake-commands-qtqml}{Qt6::Qml}
            \li \l{cmake-macros-qtremoteobjects}{Qt6::RemoteObjects}
            \li \l{cmake-macros-qtscxml}{Qt6::Scxml}
            \li \l{cmake-macros-qtwidgets}{Qt6::Widgets}
            \li \l{cmake-commands-qtwebenginecore}{Qt6::WebEngineCore}
        \endlist
        \li \l{CMake Variable Reference}
        \list
            \li \l{Module variables}
            \li \l{Installation variables}
            \li \l{Project variables}
        \endlist
        \li \l{CMake Property Reference}
        \list
            \li \l{cmake-properties-qtcore}{Qt6::Core}
            \li \l{cmake-properties-qtdbus}{Qt6::DBus}
            \li \l{cmake-properties-qtqml}{Qt6::Qml}
        \endlist
    \endlist
*/

/*!
    \page cmake-get-started.html
    \title Getting started with CMake
    \previouspage Build with CMake
    \nextpage Building projects on the command line

    \c{CMake} is a group of tools that allow to build, test, and package
    applications. Just like Qt, it is available on all major development
    platforms. It is also supported by various IDE's, including
    \l{Qt Creator Manual}{Qt Creator}.

    In this section we will show the most basic way to use Qt in a CMake
    project. First, we create a basic console application. Then, we extend the
    project into a GUI application that uses \l{Qt Widgets}.

    If you want to know how to build an existing CMake project with Qt, see the
    documentation on \l{Building projects on the command line}{how to build
    projects with CMake on the command line}.

    \section2 Building a C++ console application

    A \c{CMake} project is defined by files written in the CMake language.
    The main file is called \c{CMakeLists.txt}, and is usually placed in the
    same directory as the actual program sources.

    Here is a typical \c{CMakeLists.txt} file for a console application written
    in C++ using Qt:

    \quotefile snippets/cmake/helloworld_qtcore.cmake

    Let's go through the content.

    \quotefromfile snippets/cmake/helloworld_qtcore.cmake

    \printuntil cmake_minimum_required

    \c cmake_minimum_required() specifies the minimum CMake version that the
    application requires. Qt itself requires at least CMake version 3.16.
    If you use a Qt that was built statically - the default in \l{Qt for iOS} and
    \l{Qt for WebAssembly} - you need CMake 3.21.1 or newer.

    \printuntil project(

    \c project() sets a project name and the default project version. The
    \c{LANGUAGES} argument tells CMake that the program is written in C++.

    \printuntil CMAKE_CXX_STANDARD_REQUIRED

    Qt 6 requires a compiler supporting C++ version 17 or newer.
    Enforcing this by setting the \c{CMAKE_CXX_STANDARD},
    \c{CMAKE_CXX_STANDARD_REQUIRED} variables will let CMake print an error if
    the compiler is too old.

    \printuntil find_package(

    This tells CMake to look up Qt 6, and import the \c {Core} module. There
    is no point in continuing if \c{CMake} cannot locate the module, so we do
    set the \c{REQUIRED} flag to let CMake abort in this case.

    If successful, the module will set some CMake variables documented in
    \l{Module variables}. It furthermore imports the \c{Qt6::Core} target
    that we use below.

    For \c{find_package} to be successful, \c CMake must find the Qt
    installation. There are different ways you can tell \c CMake about Qt,
    but the most common and recommended approach is to set the CMake cache
    variable \c{CMAKE_PREFIX_PATH} to include the Qt 6 installation prefix.
    Note that \l{Qt Creator Manual}{Qt Creator} will handle this transparently
    for you.

    \printuntil qt_standard_project_setup(

    The \l{qt6_standard_project_setup}{qt_standard_project_setup} command sets
    project-wide defaults for a typical Qt application.

    Among other things, this command sets the \c{CMAKE_AUTOMOC} variable to
    \c{ON}, which instructs CMake to automatically set up rules so that Qt's
    \l{Using the Meta-Object Compiler (moc)}{Meta-Object Compiler (moc)} is
    called transparently, when required.

    See \l{qt6_standard_project_setup}{qt_standard_project_setup}'s reference
    for details.

    \printuntil )

    \c{add_executable()} tells CMake that we want to build an executable (so not
    a library) called \c{helloworld} as a target. The target should be built
    from the C++ source file \c{main.cpp}.

    Note that you typically do not list header files here. This is different
    from \l{qmake}, where header files need to be explicitly listed so that
    they are processed by the
    \l{Using the Meta-Object Compiler (moc)} {Meta-Object Compiler (moc)}.

    For less trivial projects, you may want to call
    \l{qt6_add_executable}{qt_add_executable()} instead. It is a wrapper around
    the built-in \c add_executable() command, providing additional logic to
    automatically handle things like linking of Qt plugins in static Qt builds,
    platform-specific customization of library names and so on.

    For creating libraries, see \l{qt6_add_library}{qt_add_library}.

    \printuntil

    Finally, \c{target_link_libraries} tells CMake that the \c{helloworld}
    executable makes use of \l{Qt Core} by referencing the \c{Qt6::Core}
    target imported by the \c{find_package()} call above. This will not only add
    the right arguments to the linker, but also makes sure that the right
    include directories, compiler definitions are passed to the C++ compiler.
    The \c{PRIVATE} keyword is not strictly necessary for an executable target,
    but it is good practice to specify it. If \c{helloworld} was a library
    rather than an executable, then either \c{PRIVATE} or \c{PUBLIC} should be
    specified (\c{PUBLIC} if the library mentions anything from \c{Qt6::Core}
    in its headers, \c{PRIVATE} otherwise).

    \section2 Building a C++ GUI application

    In the \l{Building a C++ console application}{last section} we showed the
    CMakeLists.txt file for a simple console application. We will now extend it
    to create a GUI application that uses the \l{Qt Widgets} module.

    This is the full project file:

    \quotefile snippets/cmake/helloworld_qtwidgets.cmake

    Let's walk through the changes we have made.

    \quotefromfile snippets/cmake/helloworld_qtwidgets.cmake
    \skipto find_package(
    \printuntil find_package(

    In the \c{find_package} call, we replace \c{Core} with \c{Widgets}. This
    will locate the \c{Qt6Widgets} module and provide the \c{Qt6::Widgets}
    targets we later link against.

    Note that the application will still link against \c{Qt6::Core}, because
    \c{Qt6::Widgets} depends on it.

    \printuntil qt_standard_project_setup(

    In addition to \c{CMAKE_AUTOMOC},
    \l{qt6_standard_project_setup}{qt_standard_project_setup} sets the
    \c{CMAKE_AUTOUIC} variable to \c{ON}. This will automatically create rules
    to invoke Qt's \l{User Interface Compiler (uic)} on \c{.ui} source files.

    \printuntil )

    We add a \l{Qt Designer} file (\c{mainwindow.ui}) and its corresponding C++
    source file (\c{mainwindow.cpp}) to the application target's sources.

    \printuntil target_link_libraries

    In the \c{target_link_libraries} command, we link against \c{Qt6::Widgets}
    instead of \c{Qt6::Core}.

    \printuntil

    Finally, we set properties on our application target with the following
    effects:

    \list
        \li Prevent the creation of a console window on Windows.
        \li Create an application bundle on macOS.
    \endlist

    See the \l{CMake Documentation} for more information about these target
    properties.

    \section2 Structuring projects

    Projects that contain more than just one target will benefit from a clear
    project file structure. We will use CMake's \l{CMake add_subdirectory
    documentation}{subdirectory feature}.

    As we plan to extend the project with more targets, we move the source files
    of the application into a subdirectory and create a new \c{CMakeLists.txt}
    in there.

    \badcode
    <project root>
    ├── CMakeLists.txt
    └── src
        └── app
            ├── CMakeLists.txt
            ├── main.cpp
            ├── mainwindow.cpp
            ├── mainwindow.h
            └── mainwindow.ui
    \endcode

    The top-level \c{CMakeLists.txt} contains the overall project setup,
    \c{find_package} and \c{add_subdirectory} calls:

    \quotefile snippets/cmake/helloworld_subdirs.cmake

    Variables that are set in this file are visible in subdirectory project
    files.

    The application's project file \c{src/app/CMakeLists.txt} contains the
    executable target:

    \quotefile snippets/cmake/helloworld_src_app.cmake

    Such a structure will make it easy to add more targets to the project such
    as libraries or unit tests.

    \section2 Building libraries

    As the project grows, you may want to turn parts of your application code
    into a library that is used by the application and possibly unit tests. This
    section shows how to create such a library.

    Our application currently contains business logic directly in \c{main.cpp}.
    We extract the code into a new static library called \c{businesslogic} in
    the subdirectory \c{"src/businesslogic"} as explained in the \l{Structuring
    projects}{previous section}.

    For the sake of simplicity, the library consists of just one C++ source file
    and its corresponding header file that is included by the application's
    \c{main.cpp}:

    \badcode
    <project root>
    ├── CMakeLists.txt
    └── src
        ├── app
        │   ├── ...
        │   └── main.cpp
        └── businesslogic
            ├── CMakeLists.txt
            ├── businesslogic.cpp
            └── businesslogic.h
    \endcode

    Let's have a look at the library's project file (\c{src/businesslogic/CMakeLists.txt}).

    \quotefile snippets/cmake/helloworld_src_businesslogic.cmake

    Let's go through the content.

    \quotefromfile snippets/cmake/helloworld_src_businesslogic.cmake
    \printuntil )

    The
    \l{https://cmake.org/cmake/help/latest/command/add_library.html}{add_library}
    command creates the library \c{businesslogic}. Later, we will let the
    application link against this target.

    The \c STATIC keyword denotes a static library. If we wanted to create a
    shared or dynamic library, we would use the \c SHARED keyword.

    \printuntil target_link_libraries

    We have a static library and don't actually have to link other libraries.
    But as our library uses classes from \c{QtCore}, we add a link dependency to
    \c{Qt6::Core}. This pulls in the necessary \c QtCore include paths and
    preprocessor defines.

    \printuntil target_include_directories

    The library API is defined in the header file
    \c{businesslogic/businesslogic.h}. By calling \l{CMake
    target_include_directories documentation}{target_include_directories}, we
    make sure that the absolute path to the \c businesslogic directory is
    automatically added as an include path to all targets using our library.

    This frees us in \c{main.cpp} from using relative paths to locate
    \c{businesslogic.h}. Instead, we can just write

    \badcode
    #include <businesslogic.h>
    \endcode

    Last, we must add the library's subdirectory to the top-level project file:

    \quotefile snippets/cmake/helloworld_subdirs2.cmake

    \section2 Using libraries

    To use the library we created in the \l{Building libraries}{previous
    section}, we instruct CMake to link against it:

    \quotefile snippets/cmake/helloworld_src_app2.cmake

    This ensures that \c{businesslogic.h} is found when main.cpp is compiled.
    Furthermore, the businesslogic static library will become a part of the \c
    helloworld executable.

    In CMake terms, the library \c businesslogic specifies \e{usage
    requirements} (the include path) that every consumer of our library (the
    application) has to satisfy. The \c{target_link_libraries} command takes
    care of that.

    \section2 Adding resources

    We want to display some images in our application, so we add them using the
    \l{The Qt Resource System}{Qt Resource System}.

    \quotefile snippets/cmake/helloworld_resources.cmake

    The \l{qt_add_resources} command automatically creates a Qt resource
    containing the referenced images. From the C++ source code, you can access
    the images by prepending the specified resource prefix:

    \code
    logoLabel->setPixmap(QPixmap(":/images/logo.png"));
    \endcode

    The \l{qt_add_resources} command takes as the first argument either a
    variable name or a target name. We recommend to use the target-based variant
    of this command as shown in the example above.

    \section2 Adding translations

    Translations of strings in a Qt project are encoded in \c{.ts} files. See
    \l{Internationalization with Qt} for details.

    To add \c{.ts} files to your project, use the
    \l{qt6_add_translations}{qt_add_translations} command.

    The following example adds a German and a French translation file to the
    \c{helloworld} target:

    \quotefile snippets/cmake/helloworld_translations.cmake

    This creates build system rules to automatically generate \c{.qm} files from
    the \c{.ts} files. By default, the \c{.qm} files are embedded into a
    resource and are accessible under the \c{"/i18n"} resource prefix.

    To update the entries in the \c{.ts} file, build the \c{update_translations}
    target:

    \badcode
    $ cmake --build . --target update_translations
    \endcode

    To trigger the generation of the \c{.qm} files manually, build the
    \c{release_translations} target:

    \badcode
    $ cmake --build . --target release_translations
    \endcode

    For more information about how to influence the handling of \c{.ts} files and
    the embedding into a resource, see the
    \l{qt6_add_translations}{qt_add_translations documentation}.

    The \l{qt6_add_translations}{qt_add_translations} command is a convenience
    wrapper. For more fine-grained control of how \c{.ts} files and \c{.qm}
    files are handled, use the underlying commands
    \l{qt6_add_lupdate}{qt_add_lupdate} and
    \l{qt6_add_lrelease}{qt_add_lrelease}.

    \section2 Further reading

    The official \l{CMake Documentation} is an invaluable source for working
    with CMake.

    The official \l{CMake Tutorial} covers common build system tasks.

    The book \l{Professional CMake: A Practical Guide} provides a great
    introduction to the most relevant CMake features.
*/

/*!
    \page cmake-build-qml-application.html
    \title Building a QML application
    \previouspage Getting started with CMake
    \nextpage Building a reusable QML module

    In \l{Building a C++ console application} we showed the
    CMakeLists.txt file for a simple console application. We will now extend it
    to create a QML application that uses the \l{Qt Quick} module.

    This is the full project file:
    \quotefile snippets/cmake/helloworld_qtqml.cmake

    Let's walk through the changes we have made.
    We specify \l {Building a C++ GUI application}{CMAKE_AUTOMOC},
    \l{Building a C++ console application}{CMAKE_CXX_STANDARD},
    and CMAKE_CXX_STANDARD_REQUIRED.

    \quotefromfile snippets/cmake/helloworld_qtqml.cmake
    \skipto CMAKE_AUTOMOC
    \printuntil CMAKE_CXX_STANDARD_REQUIRED

    In the \c{find_package} call, we replace \c{Core} with \c{Quick}. This
    will locate the \c{Qt6Quick} module and provide the \c{Qt6::Quick}
    targets we later link against.

    \printuntil find_package(

    Note that the application will still link against \c{Qt6::Core}, because
    \c{Qt6::Quick} depends on it.

    \l {qt_add_executable} creates and finalizes an application target:

    \printuntil )

    \l {qt_add_qml_module} passes the target of the executable, a URI, module
    version, and a list of QML files to ensure that myapp becomes a
    QML module. Among other things, this places the QML files into
    \c { qrc:/${URI} } in the resource file system.

    \printuntil )

    First, \c qt_add_qml_module ensures that \c qmlcachegen runs. Second, it
    creates a \c myapp_qmllint target, which runs \c qmllint on the files in
    QML_FILES.

    By adding the referenced resources, they get automatically added to
    the application under the same root path as the QML files – also in the
    resource file system. By keeping the path in the resource system
    consistent with the one in the source and build directory, we ensure that
    the image is always found, as it is resolved relative to FramedImage.qml.
    It refers to the image in the resource file system if we load main.qml from
    there, or to the one in the actual file system if we review it with
    the \c qml tool.

    In the \c{target_link_libraries} command, we link against \c{Qt6::Quick}
    instead of \c{Qt6::Core}.

    \printuntil target_link_libraries
*/

/*!
    \page cmake-build-reusable-qml-module.html
    \title Building a reusable QML module
    \previouspage Building a QML application
    \nextpage Building projects on the command line

    The example below demonstrates how to create a library which exposes C++ to QML.
    The directory structure for the example looks like this:

    \badcode
    ├── CMakeLists.txt
    └── example
        └── mylib
            ├── CMakeLists.txt
            ├── mytype.cpp
            ├── mytype.h
    \endcode

    The toplevel \c CMakeLists.txt file does some basic setup, and then uses
    \c add_subdirectory to include the one in mylib. The subdirectory structure
    corresponds to the QML module’s URI, but with the dots replaced by
    slashes. That’s the same logic the engine uses when it searches for a
    module in the \l{Import Statements}{import paths}. \c mytype.h declares a
    class and uses the
    declarative registration macros to expose it to the engine.

    In the subdirectory’s \c CMakeLists.txt we again call \c qt6_add_qml_module.
    However, the invocation is slightly different:

    \quotefromfile snippets/cmake/helloworld_subdirs_qml.cmake
    \printuntil mytype.h
    \skipto )
    \printuntil )

    To add C++ types, the SOURCES parameter needs to be specified. The target for
    mylib is not created. Therefore, if the target passed to \c qt6_add_qml_module
    does not exist, a library target is automatically created, which is needed in
    this case.

    When the project is built, in addition to the library, a QML plugin is also
    built. The plugin's auto-generated class extends from
    \c {QQmlEngineExtensionPlugin}.
    The mylib library itself already contains the code to register the types
    with the engine.  However, that is only useful in cases where we can link
    against the library. To make the module usable in a QML file loaded by \c qml,
    the \l{qml_runtime_tool}{QML Runtime Tool}, a plugin is needed that can be loaded.
    The plugin is then responsible for actually linking against the library, and
    ensuring that the types get registered.

    Note that the automatic plugin generation is only possible if the module
    does not do anything besides registering the types. If it needs to do
    something more advanced like registering an image provider in
    \c initializeEngine, you still need to manually write the plugin.
    \l{qt6_add_qml_module} has support for this with \c NO_GENERATE_PLUGIN_SOURCE.

    Also, following the directory layout convention helps tooling. That layout
    is mirrored in the build directory. Which means that you can pass the path to
    your build directory to the QML tool (via the -I flag), and it will find the
    plugin.

    Before concluding add a QML file to the module. In the lib subfolder,
    add a \c Mistake.qml file
    \code
    import example.mylib

    MyType{
        answer: 43
    }
    \endcode

    and adjust the \c qt6_add_qml_module call:

    \quotefile snippets/cmake/helloworld_subdirs_qml.cmake

    As mentioned, we made a mistake because \c answer is actually a read-only
    property. This illustrates \c qmllint integration: CMake
    creates a \c qmllint target, and once we run it, \c qmllint warns
    about the issue:

    \badcode
    $> cmake --build . --target mylib_qmllint
    ...
    Warning: Mistake.qml:4:13: Cannot assign to read-only property answer
        answer: 43
                ^^
    \endcode
*/

/*!
    \page cmake-build-on-cmdline.html
    \title Building projects on the command line
    \previouspage Getting started with CMake
    \nextpage Imported targets

    This page explains how to configure and build existing projects. If you want
    to know how to create a Qt-based CMake project, see the documentation on
    \l{Getting started with CMake}{how to get started with CMake}.

    To build a Qt project, CMake needs to know where the Qt installation is
    located. Usually this is done by setting the CMake variable \l{CMake
    CMAKE_PREFIX_PATH documentation}{CMAKE_PREFIX_PATH} to Qt's installation
    prefix. If you are cross-compiling, see \l{Cross-compiling} for details on
    additional variables you will need to set.

    If Qt is installed using the online installer, choose a Qt version within
    the top-level installation directory. For example, the following command
    shows how this is done on Windows:

    \badcode \QtVersion
    cmake -DCMAKE_PREFIX_PATH=C:\Qt\\1\msvc2019_64 -S <source-dir> -B <build-dir>
    \endcode

    The \c{<source-dir>} and \c{<build-dir>} placeholders represent the source
    and build directories of your project.

    \section1 CMake generators

    CMake generates the necessary build system files that enable build tools
    such as GNU Make or Ninja to build your project.

    CMake's default generator depends on the platform and build environment. For
    example on Windows, CMake generates Visual Studio project files if a Visual
    Studio environment is detected.

    For a consistent developer experience on all platforms, use the \c{Ninja} or
    \c{Ninja Multi-Config} generator.

    You can select the CMake generator either by setting the \c{CMAKE_GENERATOR}
    environment variable or using the \c{-G} argument:

    \badcode
    cmake -G Ninja ...
    \endcode

    \section1 qt-cmake

    The \c{qt-cmake} script is a convenient alternative to configure your
    project. It eliminates the need for you to specify the
    \c{CMAKE_PREFIX_PATH}. You can find it located in the \c{bin} directory of
    your Qt installation prefix. The script passes all parameters to CMake, so
    you can use it just like you would \c{cmake\}:

    \badcode \QtVersion
    C:\Qt\\1\msvc2019_64\bin\qt-cmake -G Ninja -S <source-dir> -B <build-dir>
    \endcode

    After the build system files are generated, your project is ready to be
    built:

    \badcode
    cd <build-dir>
    ninja
    \endcode

    You can also use the generator-independent CMake command:

    \badcode
    cmake --build <build-dir>
    \endcode

    \section1 Cross-compiling

    Building your project for a platform that is different from your development
    machine is called cross-compiling. An example is building for Android (the
    target platform) on a Windows machine (the host platform).

    Cross-compiling with CMake requires a \l{CMake CMAKE_TOOLCHAIN_FILE
    documentation}{toolchain file} for most platforms. It also requires a Qt
    version for the development host, in addition to a Qt version for the target
    platform. For example, you need Qt for Windows and Qt for Android installed
    to cross-compile for Android on Windows.

    Use \c qt-cmake from the Qt installation for the target platform, to
    cross-compile your project for that platform:

    \badcode
    <target-qt>/bin/qt-cmake -S <source-dir> -B <build-dir>
    \endcode

    This will configure your project for the target platform. The toolchain file
    is automatically passed, and possibly other platform-specific variables are
    set up.

    \section1 Specifying a custom toolchain file

    The \c{qt-cmake} script passes a Qt-internal \l{CMake CMAKE_TOOLCHAIN_FILE
    documentation}{toolchain file} to CMake. This toolchain file sets several
    variables that are specific to Qt's target platform.

    If you are using a Qt installation that has not been built on your machine,
    \c{qt-cmake} needs to know the location of the CMake toolchain file for the
    target platform.

    In such a case, you can instruct \c{qt-cmake} to chainload a custom
    toolchain file by setting the \c{QT_CHAINLOAD_TOOLCHAIN_FILE} variable:

    \badcode \QtVersion
    ~/Qt/\1/android_armv7/bin/qt-cmake -DQT_CHAINLOAD_TOOLCHAIN_FILE=<file-path> -S <source-dir> -B <build-dir>
    \endcode

    This instructs Qt's internal toolchain file to load your custom toolchain
    file as well.
*/

/*!
    \page cmake-imported-targets.html
    \title Imported targets
    \brief Provides an overview of the CMake targets imported by Qt.
    \nextpage Qt 5 and Qt 6 compatibility
    \previouspage Building projects on the command line

    Each Qt module that is loaded defines a CMake library target. The target names
    start with \c{Qt6::}, followed by the module name. For example: \c{Qt6::Core}, \c{Qt6::Gui}.
    Pass the name of the library target to \c target_link_libraries to use the respective library.

    \note The targets are also available with a \c{Qt::} prefix:
    \c Qt::Core, \c Qt::Gui, and so on. See also \l{Qt 5 and Qt 6 compatibility}.

    Imported targets are created with the same configurations as when Qt was configured. That is:
    \list
        \li If Qt was configured with the \c -debug switch, an imported target with the DEBUG
            configuration is created.
        \li If Qt was configured with the \c -release switch, an imported target with the RELEASE
            configuration is created.
        \li If Qt was configured with the \c -debug-and-release switch, then imported targets are
            created with both RELEASE and DEBUG configurations.
    \endlist

    If your project has custom \c{CMake} build configurations, you have to map your custom
    configuration to either the debug or the release Qt configuration.

    \snippet snippets/cmake/examples.cmake 2
*/


/*!
    \page cmake-qt5-and-qt6-compatibility.html
    \title Qt 5 and Qt 6 compatibility
    \previouspage Imported targets
    \nextpage CMake Command Reference

    The semantics of the CMake API in Qt 5 and Qt 6 are largely compatible. However, up to Qt 5.14,
    all imported Qt library targets and commands contained the version number as part of the name.
    This makes writing CMake code that should work with both Qt 5 and Qt 6 somewhat cumbersome.
    Qt 5.15 therefore introduced \e versionless targets and commands to enable writing CMake code
    that is largely agnostic to the different Qt versions.

    \section2 Versionless targets

    In addition to the existing imported targets, Qt 5.15 introduced \e versionless targets. That
    is, to link against \l{Qt Core} one can both reference \c Qt6::Core, or \c Qt::Core:

    \snippet snippets/cmake/qt5_qt6_compatible.cmake versionless_targets

    Above snippet first tries to find a Qt 6 installation. If that fails, it tries to find a
    Qt 5.15 package. Independent of whether Qt 6 or Qt 5 is used, we can use the imported
    \c{Qt::Core} target.

    The versionless targets are defined by default. Set \l{QT_NO_CREATE_VERSIONLESS_TARGETS}
    before the first \c{find_package()} call to disable them.

    \note The imported Qt::Core target will not feature the target properties that are available
    in the Qt6::Core target.

    \section2 Versionless commands

    Since Qt 5.15, the Qt modules also provide versionless variants of their
    \l{CMake Command Reference}{commands}. You can for instance now use \l{qt_add_translation}
    to compile translation files, independent of whether you use Qt 5 or Qt 6.

    Set \l{QT_NO_CREATE_VERSIONLESS_FUNCTIONS} before the first \c{find_package()} call to
    prevent the creation of versionless commands.

    \section2 Mixing Qt 5 and Qt 6

    There might be projects that need to load both Qt 5 and Qt 6 in one CMake context
    (though mixing Qt versions in one library or executable is not supported, so be careful there).

    In such a setup the versionless targets and commands will be implicitly referring to the first
    Qt version that was found via \c{find_package}. Set the \l{QT_DEFAULT_MAJOR_VERSION} CMake
    variable before the first \c{find_package} call to make the version explicit.

    \section2 Supporting older Qt 5 versions

    If you need to support also Qt 5 versions older than Qt 5.15, you can do so by storing the
    current version in an CMake variable:

    \snippet snippets/cmake/qt5_qt6_compatible.cmake older_qt_versions

    Here we let \c{find_package(<PackageName>...)} try to find first Qt 6, and if
    that fails Qt 5, under the name \c{QT}. If either of them is found, \c find_package will
    succeed, and the CMake variable \c{QT_VERSION_MAJOR} will be defined to either \c{5} or \c{6}.

    We then do load the package for the determined Qt version again by creating the name
    \c{Qt${QT_VERSION_MAJOR}} on the fly. This is needed because \c{CMAKE_AUTOMOC}
    expects the package name to be either \c{Qt5} or \c{Qt6}, and will print an error otherwise.

    We can use the same pattern to also specify the name of the imported library.
    Before calling \c{target_link_libraries}, CMake will resolve \c{Qt${QT_VERSION_MAJOR}::Widgets}
    to either \c{Qt5::Widgets} or \c{Qt6::Widgets}.

    \section2 Recommended practices

    Use the versionless variants of the CMake commands where possible.

    Versionless imported targets are mostly useful for projects that need to compile with both
    Qt 5 and Qt 6. Because of the missing target properties, we do not recommend using
    them by default.

    Use the versioned versions of the CMake commands and targets if you need to support Qt 5
    versions older than Qt 5.15, or if you cannot control whether your CMake code is
    loaded in a context where \l{QT_NO_CREATE_VERSIONLESS_FUNCTIONS} or
    \l{QT_NO_CREATE_VERSIONLESS_TARGETS} might be defined. In this case you can still simplify
    your code by determining the actual command or target name through a variable.

    \section2 Unicode support in Windows

    In Qt 6, the \c UNICODE and \c{_UNICODE} compiler definitions are set by default for targets that link
    against Qt modules. This is in line with the qmake behavior, but it is a change compared to
    the CMake API behavior in Qt 5.

    Call \l{qt6_disable_unicode_defines}{qt_disable_unicode_defines()} on the target to not set the definitions.

    \snippet snippets/cmake/qt5_qt6_compatible.cmake disable_unicode_defines
*/

/*!
    \page cmake-variable-reference.html
    \title CMake Variable Reference
    \brief Provides a complete reference for CMake variables implemented in Qt.
    \nextpage CMake Property Reference
    \previouspage CMake Command Reference

    \section1 Module variables

    Qt modules loaded with \c{find_package} set various variables.

    \note You rarely need to access these variables directly. Common tasks like linking against a
    module should be done through the library targets each module defines.

    For example, \c{find_package(Qt6 COMPONENTS Widgets)}, when successful, makes the following
    variables available:

    \table
        \header
            \li Variable
            \li Description
        \row
            \li \c Qt6Widgets_COMPILE_DEFINITIONS
            \li A list of compile definitions to use when building against the library.
        \row
            \li \c Qt6Widgets_DEFINITIONS
            \li A list of definitions to use when building against the library.
        \row
            \li \c Qt6Widgets_EXECUTABLE_COMPILE_FLAGS
            \li A string of flags to use when building executables against the library.
        \row
            \li \c Qt6Widgets_FOUND
            \li A boolean that describes whether the module was found successfully.
        \row
            \li \c Qt6Widgets_INCLUDE_DIRS
            \li A list of include directories to use when building against the library.
        \row
            \li \c Qt6Widgets_LIBRARIES
            \li The name of the imported target for the module: \c Qt5::Widgets
        \row
            \li \c Qt6Widgets_PRIVATE_INCLUDE_DIRS
            \li A list of private include directories to use when building against the library
                and using private Qt API.
        \row
            \li \c Qt6Widgets_VERSION_STRING
            \li A string containing the module's version.
    \endtable

    For all packages found with \c{find_package}, equivalents of these variables are available;
    they are case-sensitive.

    \section1 Installation variables

    Additionally, there are also variables that don't relate to a particular package, but to the
    Qt installation itself.

   \table
        \header
            \li Variable
            \li Description
        \row
            \li \target QT_DEFAULT_MAJOR_VERSION
                \c QT_DEFAULT_MAJOR_VERSION
            \li An integer that controls the Qt version that \c qt_ commands forward to in case of
                mixed Qt 5 and Qt 6 projects. It needs to be set to either \c 5 or \c 6 before the
                respective \c find_package() calls.

                If set to \c 5, commands starting with \c qt_ will call their counterpart starting
                with \c qt5_. If set to \c 6, they will call their counterpart starting with
                \c qt6_.

                If not set, the first \c find_package call defines the default version.
        \row
            \li \c QT_LIBINFIX
            \li A string that holds the infix used in library names, when Qt is configured with
                \c{-libinfix}.
        \row
            \li \target QT_NO_CREATE_VERSIONLESS_FUNCTIONS
                \c QT_NO_CREATE_VERSIONLESS_FUNCTIONS
            \li Hides commands that start with \c{qt_}, leaving only the versioned
                ones starting with \c{qt6_}.
        \row
            \li \target QT_NO_CREATE_VERSIONLESS_TARGETS
                \c QT_NO_CREATE_VERSIONLESS_TARGETS
            \li Hides the imported targets starting with \c{Qt::}. Instead, you need to use the
                targets starting with \c{Qt6::}.
        \row
            \li \c QT_VISIBILITY_AVAILABLE
            \li On Unix, a boolean that describes whether Qt libraries and plugins were compiled
                with \c{-fvisibility=hidden}. This means that only selected symbols are exported.
    \endtable

    \section1 Project variables

    These variables can influence CMake commands provided by Qt. They may be set
    by the project, a toolchain file or other third-party packages.

    \section2 Qt6::Core

    \annotatedlist cmake-variables-qtcore

    \section2 Qt6::Qml

    \annotatedlist cmake-variables-qtqml

    \section2 Qt6::InterfaceFramework

    \annotatedlist cmake-variables-qtinterfaceframework
*/

/*!
    \page cmake-property-reference.html
    \title CMake Property Reference
    \brief Provides a complete reference for CMake properties implemented in Qt.
    \previouspage CMake Variable Reference

    \section1 Qt6::Core
    \target cmake-properties-qtcore

    \section2 Target Properties

    \annotatedlist cmake-target-properties-qtcore

    \section2 Source File Properties

    \annotatedlist cmake-source-file-properties-qtcore

    \section1 Qt6::DBus
    \target cmake-properties-qtdbus

    \section2 Source File Properties

    \annotatedlist cmake-source-file-properties-qtdbus

    \section1 Qt6::Qml
    \target cmake-properties-qtqml

    \section2 Source File Properties

    \annotatedlist cmake-source-file-properties-qtqml
*/

/*!
    \page cmake-command-reference.html
    \title CMake Command Reference
    \brief Provides a complete reference for CMake commands implemented in Qt.
    \previouspage Qt 5 and Qt 6 compatibility
    \nextpage CMake Variable Reference

    \section2 Qt6::Core
    \target cmake-commands-qtcore

    \annotatedlist cmake-commands-qtcore

    \section2 Qt6::DBus
    \target cmake-commands-qtdbus

    \annotatedlist cmake-commands-qtdbus

    \section2 Qt6::InterfaceFramework
    \target cmake-macros-qtinterfaceframework

    \annotatedlist cmake-macros-qtinterfaceframework

    \annotatedlist cmake-commands-qtdbus

    \section2 Qt6::LinguistTools
    \target cmake-macros-qtlinguisttools

    \annotatedlist cmake-macros-qtlinguisttools

    \section2 Qt6::Qml
    \target cmake-commands-qtqml

    \annotatedlist cmake-commands-qtqml

    \section2 Qt6::RemoteObjects
    \target cmake-macros-qtremoteobjects

    \annotatedlist cmake-macros-qtremoteobjects

    \section2 Qt6::Scxml
    \target cmake-macros-qtscxml

    \annotatedlist cmake-macros-qtscxml

    \section2 Qt6::Widgets
    \target cmake-macros-qtwidgets

    \annotatedlist cmake-macros-qtwidgets

    \target cmake-commands-qtwebenginecore
    \section2 Qt6::WebEngineCore

    \annotatedlist cmake-commands-qtwebenginecore
*/
