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

/*!
    \page resources.html
    \title The Qt Resource System
    \brief A platform-independent mechanism for shipping resource files in an
    application.

    \keyword resource system

    The Qt resource system is a platform-independent mechanism for shipping
    resource files in an application. Use it if your application always needs a
    certain set of files (like icons, translation files, images), and you don't
    want to use system-specific means to package and locate these resources.

    Most commonly, the resource files are embedded into your application
    executable, or in libraries and plugins that are loaded by the application
    executable. Alternatively, the resource files can also be stored in an
    \l{External Resource Files}{external resource file}.

    The resource system is based on tight cooperation between Qt's \l rcc
    resource compiler, the build system, and the Qt runtime API.

    \note Currently, the Qt resource system does not make use of any
    system-specific capabilities for handling resources, such as the ones on
    Windows, \macos, and iOS. This might change in a future Qt release.

    \section1 The Qt Resource Compiler (rcc)

    The \l{Resource Compiler (rcc)} command line tool reads resource files and
    generates either a C++ or Python source file, or an \c .rcc file.

    The list of files and related metadata is passed to \c rcc in the form of a
    \l{Qt Resource Collection File}.

    By default, rcc will generate C++ source code that is then compiled as part
    of an executable or library. The \c{-g python} option generates Python
    source code instead. The \c -binary option generates a binary archive that
    is by convention saved in an \c .rcc file and can be loaded at runtime.

    \note While it is possible to run \c rcc from the command line, this is
    typically best left to a build system. See also the sections about
    \l{qmake} and \l{CMake} below.

    \section1 Qt Resource Collection File (.qrc)
    \target {Qt Resource Collection File}
    \target {Resource Collection Files}

    A \c .qrc file is an XML document that enumerates local files to be
    included as runtime resources. It serves as input to \c{rcc}.

    Here's an example \c .qrc file:

    \quotefile resource-system/application.qrc

    Each \c <file> element in the XML identifies a file in the application's
    source tree. The path is resolved relative to the directory containing
    the \c .qrc file.

    The path is also used by default to identify the file's content at runtime.
    That is, the file \c titlebarLeft.png will be available in the resource system as
    \c{:/res/titlebarLeft.png} or \c{qrc:/res/titlebarLeft.png}.
    To override this default run-time name, see \l{Prefixes} and \l{Aliases}.

    \e{Qt Creator}, \e{Qt Design Studio}, \QD, and \e{Qt Visual Studio Tools}
    allow you to create, inspect and edit \c .qrc files through a convenient
    user interface. Except for \QD, they also provide wizards for projects
    using the Qt resource system.

    \section1 Build System Integration

    The processing of resource files with \c rcc is typically done at the time
    the application is built. Several build tools have dedicated support for
    this, including \l CMake and \l qmake.

    \section2 CMake

    If \c CMAKE_AUTORCC is enabled, you can just add \c .qrc files as sources
    to your executable or library. The referenced resource files will then be
    embedded into the binary:

    \snippet resource-system/CMakeLists.txt AUTORCC

    See \l {https://cmake.org/cmake/help/latest/prop_tgt/AUTORCC.html}
    {CMake's AUTORCC documentation} for more details about AUTORCC.

    An alternative to AUTORCC is using Qt6Core's CMake function
    \l qt_add_resources, which gives more control over the creation of
    resources. For example, it allows you to specify the content of the
    resource directly in the project file without writing a \c .qrc file first:

    \snippet resource-system/CMakeLists.txt qt_add_resources

    Finally, \l qt_add_qml_module allows you to embed Qt Quick resources into
    the resource system of your application. The function is defined in the
    \c Qml component of the \c Qt6 CMake package.

    \section2 qmake

    \l{qmake Manual}{qmake} supports handing resources with the \l{RESOURCES}
    variable. If you add a \c .qrc file path to the variable, the listed
    resource files will be embedded into the generated library or executable:

    \snippet resource-system/application.pro qrc

    This creates a resource of several \c{.png} files, that are addressable
    like this: \c{":/res/titlebarLeft.png"}.

    If the directory layout of the files you want to embed into the resource
    doesn't match the expectations of the application, you can specify
    \c{resources.base}. \c base is a path prefix that denotes the root point of
    the file's alias. In the example above, if \c{resources.base} is set to
    \c{"res"}, then \c{titlebarLeft.png} is addressable as \c{":/titlebarLeft.png"}.

    \section1 Runtime API

    Qt API that deals with iterating and reading files has built-in support for
    the Qt Resource System. You can pass a resource path instead of a local
    file path to QFile and QDir, but also for instance to the QIcon, QImage, and
    QPixmap constructors:

    \snippet resource-system/mainwindow.cpp 21

    The \c : prefix makes it explicit that "/images/cut.png" should be loaded
    from the Qt Resource System.

    You can also reference the Qt resource system through a QUrl. Use the
    \c qrc scheme in this case:

    \snippet resource-system/main.cpp url

    \section1 Advanced Topics

    \section2 Prefixes

    A \c .qrc file can set a prefix to be added to each local file name, given
    in a \c <file> element, to get the name by which the file shall be known
    within the resource system.

    Prefixes allow you to structure the resources, avoiding clashes between
    resource files added through different \c .qrc files in different libraries
    or plugins.

    \note The \c /qt and \c /qt-project.org prefixes are reserved for documented
    use cases in Qt. The \l{Using qt.conf}{qt.conf} file is for instance looked
    up in \c{:/qt/etc/qt.conf} or \c{qrc:/qt/etc/qt.conf}.

    \section2 Aliases

    Sometimes it is convenient to make a resource file available under a
    different path at runtime. \c .qrc files allow this by setting an
    \c alias attribute:

    \snippet code/doc_src_resources.qdoc 0

    The file is from the application then only accessible as \c :/cut-img.png
    or \c{qrc:/cut-img.png}.

    \section2 Discarding the file contents

    Sometimes you want to add a file node to the resource file system but
    don't actually want to add the file contents. \c .qrc files allow this
    by setting the \c empty attribute to \c{true}.

    \snippet code/doc_src_resources.qdoc 4

    The resulting file is then still accessible from the application, but
    its contents are empty.

    This is useful to strip QML source code from an application binary.

    \note If you omit the QML source code from the binary, the QML engine has to
    rely on the compilation units created by \l{qmlcachegen} or \l{qmlsc}.
    Those are tied to the specific version of Qt they were built with. If you
    change the version of Qt your application uses, they can't be loaded
    anymore.

    \section2 Language Selectors

    Some resources need to change based on the user's locale, such as
    translation files or icons. \l{Resource Collection Files} support this
    through a \c lang attribute to the \c qresource tag, specifying a suitable
    locale string. For example:

    \snippet code/doc_src_resources.qdoc 2

    If the user's locale is French (i.e., QLocale::system().language() is
    French), \c :/cut.jpg or \c qrc:/cut.jpg becomes a reference to the
    \c cut_fr.jpg image. For other locales, \c cut.jpg is used.

    See the QLocale documentation for a description of the format to use for
    locale strings.

    See QFileSelector for an additional mechanism to select locale-specific
    resources.

    \section2 Embedding Large Files

    By default, \c rcc embeds the resource files into executables in the form
    of C++ arrays. This can be problematic especially for large resources.

    If the compiler takes too long, or even fails because of memory overflow,
    you can opt into a special mode where the resources are embedded as part of
    a two-step process. The C++ compiler only reserves enough space in the
    target executable or library for the resources. The actual embedding of the
    resource file's content and metadata is then done after the compilation and
    linking phase, through another rcc call.

    For CMake, you need to use the \l{qt_add_big_resources} function.

    \section2 External Resource Files

    An alternative to embedding the resource files into the binary is to store
    them in a separate \c .rcc file. \c rcc allows this with the \c -binary
    option. Such a \c .rcc file must then be loaded at runtime with QResource.

    For example, a set of resource data specified in a \c .qrc file can be
    compiled in the following way:

    \snippet code/doc_src_resources.qdoc 3

    In the application, this resource would be registered with code like this:

    \snippet code/doc_src_resources.cpp 4

    If you use CMake, you can use the \l{qt_add_binary_resources} function
    to schedule the \c rcc call above:

    \snippet resource-system/CMakeLists.txt qt_add_binary_resources

    \section2 Resources in a Qt for Python application

    The resource collection file is converted to a Python module by using the
    resource compiler \l rcc:

    \code
    rcc -g python mainwindow.qrc > mainwindow_rc.py
    \endcode

    The module can then be imported in the application:

    \code
    import mainwindow_rc.py
    \endcode

    \section2 Compression

    \c rcc attempts to compress the content to optimize disk space usage in the
    final binaries. By default, it will perform a heuristic check to determine
    whether compressing is worth it and will store the content uncompressed if
    it fails to sufficiently compress. To control the threshold, you can use
    the \c {-threshold} option, which tells \c rcc the percentage of the
    original file size that must be gained for it to store the file in
    compressed form.

    \code
        rcc -threshold 25 myresources.qrc
    \endcode

    The default value is "70", indicating that the compressed file must be 70%
    smaller than the original (no more than 30% of the original file size).

    It is possible to turn off compression if desired. This can be useful if
    your resources already contain a compressed format, such as \c .png files,
    and you do not want to incur the CPU cost at build time to confirm that it
    can't be compressed. Another reason is if disk usage is not a problem and
    the application would prefer to keep the content as clean memory pages at
    runtime. You do this by giving the \c {-no-compress} command line argument.

    \code
        rcc -no-compress myresources.qrc
    \endcode

    \c rcc also gives you some control over the compression level and
    compression algorithm, for example:

    \code
        rcc -compress 2 -compress-algo zlib myresources.qrc
    \endcode

    It is also possible to use \c threshold, \c compress, and \c compress-algo
    as attributes in a .qrc \c file tag.

    \code
    <qresource>
        <file compress="1" compress-algo="zstd">data.txt</file>
    </qresource>
    \endcode

    The above will select the \c zstd algorithm with compression level 1.

    \c rcc supports the following compression algorithms and compression
    levels:

    \list
      \li \c best: use the best algorithm among the ones below, at its highest
      compression level, to achieve the most compression at the expense of
      using a lot of CPU time during compilation. This value is useful in the
      XML file to indicate a file should be most compressed, regardless of
      which algorithms \c rcc supports.

      \li \c zstd: use the \l{Zstandard Site}{Zstandard} library to compress
      contents. Valid compression levels range from 1 to 19, 1 is least
      compression (least CPU time) and 19 is the most compression (most CPU
      time). The default level is 14. A special value of 0 tells the \c zstd
      library to choose an implementation-defined default.

      \li \c zlib: use the \l{https://zlib.net}{zlib} library to compress
      contents. Valid compression levels range from 1 to 9, with 1 applying
      the least compression (least CPU time) and 9 the most compression (most
      CPU time). The special value 0 means "no compression" and should not be
      used. The default is implementation-defined, but usually is level 6.

      \li \c none: no compression. This is the same as the \c -no-compress
      option.
    \endlist

    Support for both Zstandard and zlib are optional. If a given library was
    not detected at compile time, attempting to pass \c {-compress-algo} for
    that library will result in an error. The default compression algorithm is
    \c zstd if it is enabled, \c zlib if not.

    \section2 Explicit Loading and Unloading of Embedded Resources

    Resources embedded in C++ executable or library code are automatically
    registered to the Qt resource system in a constructor of an internal
    global variable. Since the global variables are initialized before
    main() runs, the resources are available when the program starts to
    run.

    When embedding resources in \e{static} libraries, the C++ linker might
    remove the static variables that register the resources. If you
    embed resources in a static library, you therefore need to explicitly
    register your resources by calling \l Q_INIT_RESOURCE() with the base
    name of the \c .qrc file.
    For example:

    \snippet code/doc_src_resources.cpp 5

    You can also explicitly remove registered resources from the application,
    for instance when unloading a plugin. Use \l Q_CLEANUP_RESOURCE() for this.

    Note: As the resource initializers generated by rcc are declared in the
    global namespace, your calls to \l Q_INIT_RESOURCE() and
    \l Q_CLEANUP_RESOURCE() need to be done outside any namespace.
*/
