code:
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
CPackComponent
--------------

Configure components for binary installers and source packages.

.. only:: html

  .. contents::

Introduction
^^^^^^^^^^^^

This module is automatically included by :module:`CPack`.

Certain binary installers (especially the graphical installers) generated
by CPack allow users to select individual application *components* to install.
This module allows developers to configure the packaging of such components.

Contents is assigned to components by the ``COMPONENT``
argument of CMake's :command:`install` command.  Components can be
annotated with user-friendly names and descriptions, inter-component
dependencies, etc., and grouped in various ways to customize the
resulting installer, using the commands described below.

To specify different groupings for different CPack generators use
a CPACK_PROJECT_CONFIG_FILE.

Variables
^^^^^^^^^

The following variables influence the component-specific packaging:

.. variable:: CPACK_COMPONENTS_ALL

 The list of component to install.

 The default value of this variable is computed by CPack and contains all
 components defined by the project.  The user may set it to only include the
 specified components.

 Instead of specifying all the desired components, it is possible to obtain a
 list of all defined components and then remove the unwanted ones from the
 list. The :command:`get_cmake_property` command can be used to obtain the
 ``COMPONENTS`` property, then the :command:`list(REMOVE_ITEM)` command can be
 used to remove the unwanted ones. For example, to use all defined components
 except ``foo`` and ``bar``::

   get_cmake_property(CPACK_COMPONENTS_ALL COMPONENTS)
   list(REMOVE_ITEM CPACK_COMPONENTS_ALL "foo" "bar")

.. variable:: CPACK_<GENNAME>_COMPONENT_INSTALL

 Enable/Disable component install for CPack generator <GENNAME>.

 Each CPack Generator (RPM, DEB, ARCHIVE, NSIS, DMG, etc...) has a legacy
 default behavior.  e.g.  RPM builds monolithic whereas NSIS builds
 component.  One can change the default behavior by setting this variable to
 0/1 or OFF/ON.

.. variable:: CPACK_COMPONENTS_GROUPING

 Specify how components are grouped for multi-package component-aware CPack
 generators.

 Some generators like RPM or ARCHIVE (TGZ, ZIP, ...) may generate
 several packages files when there are components, depending
 on the value of this variable:

 * ONE_PER_GROUP (default): create one package per component group
 * IGNORE : create one package per component (ignore the groups)
 * ALL_COMPONENTS_IN_ONE : create a single package with all requested
   components

.. variable:: CPACK_COMPONENT_<compName>_DISPLAY_NAME

 The name to be displayed for a component.

.. variable:: CPACK_COMPONENT_<compName>_DESCRIPTION

 The description of a component.

.. variable:: CPACK_COMPONENT_<compName>_GROUP

 The group of a component.

.. variable:: CPACK_COMPONENT_<compName>_DEPENDS

 The dependencies (list of components) on which this component depends.

.. variable:: CPACK_COMPONENT_<compName>_HIDDEN

 True if this component is hidden from the user.

.. variable:: CPACK_COMPONENT_<compName>_REQUIRED

 True if this component is required.

.. variable:: CPACK_COMPONENT_<compName>_DISABLED

 True if this component is not selected to be installed by default.

Commands
^^^^^^^^

Add component
"""""""""""""

.. command:: cpack_add_component

Describe an installation component.

::

  cpack_add_component(compname
                      [DISPLAY_NAME name]
                      [DESCRIPTION description]
                      [HIDDEN | REQUIRED | DISABLED ]
                      [GROUP group]
                      [DEPENDS comp1 comp2 ... ]
                      [INSTALL_TYPES type1 type2 ... ]
                      [DOWNLOADED]
                      [ARCHIVE_FILE filename]
                      [PLIST filename])

``compname`` is the name of an installation component, as defined by the
``COMPONENT`` argument of one or more CMake :command:`install` commands.
With the ``cpack_add_component`` command one can set a name, a description,
and other attributes of an installation component.
One can also assign a component to a component group.

DISPLAY_NAME is the displayed name of the component, used in graphical
installers to display the component name.  This value can be any
string.

DESCRIPTION is an extended description of the component, used in
graphical installers to give the user additional information about the
component.  Descriptions can span multiple lines using ``\n`` as the
line separator.  Typically, these descriptions should be no more than
a few lines long.

HIDDEN indicates that this component will be hidden in the graphical
installer, so that the user cannot directly change whether it is
installed or not.

REQUIRED indicates that this component is required, and therefore will
always be installed.  It will be visible in the graphical installer,
but it cannot be unselected.  (Typically, required components are
shown grayed out).

DISABLED indicates that this component should be disabled (unselected)
by default.  The user is free to select this component for
installation, unless it is also HIDDEN.

DEPENDS lists the components on which this component depends.  If this
component is selected, then each of the components listed must also be
selected.  The dependency information is encoded within the installer
itself, so that users cannot install inconsistent sets of components.

GROUP names the component group of which this component is a part.  If
not provided, the component will be a standalone component, not part
of any component group.  Component groups are described with the
cpack_add_component_group command, detailed below.

INSTALL_TYPES lists the installation types of which this component is
a part.  When one of these installations types is selected, this
component will automatically be selected.  Installation types are
described with the cpack_add_install_type command, detailed below.

DOWNLOADED indicates that this component should be downloaded
on-the-fly by the installer, rather than packaged in with the
installer itself.  For more information, see the
cpack_configure_downloads command.

ARCHIVE_FILE provides a name for the archive file created by CPack to
be used for downloaded components.  If not supplied, CPack will create
a file with some name based on CPACK_PACKAGE_FILE_NAME and the name of
the component.  See cpack_configure_downloads for more information.

PLIST gives a filename that is passed to pkgbuild with the
``--component-plist`` argument when using the productbuild generator.

Add component group
"""""""""""""""""""

.. command:: cpack_add_component_group

Describes a group of related CPack installation components.

::

  cpack_add_component_group(groupname
                           [DISPLAY_NAME name]
                           [DESCRIPTION description]
                           [PARENT_GROUP parent]
                           [EXPANDED]
                           [BOLD_TITLE])

The cpack_add_component_group describes a group of installation
components, which will be placed together within the listing of
options.  Typically, component groups allow the user to
select/deselect all of the components within a single group via a
single group-level option.  Use component groups to reduce the
complexity of installers with many options.  groupname is an arbitrary
name used to identify the group in the GROUP argument of the
cpack_add_component command, which is used to place a component in a
group.  The name of the group must not conflict with the name of any
component.

DISPLAY_NAME is the displayed name of the component group, used in
graphical installers to display the component group name.  This value
can be any string.

DESCRIPTION is an extended description of the component group, used in
graphical installers to give the user additional information about the
components within that group.  Descriptions can span multiple lines
using ``\n`` as the line separator.  Typically, these descriptions
should be no more than a few lines long.

PARENT_GROUP, if supplied, names the parent group of this group.
Parent groups are used to establish a hierarchy of groups, providing
an arbitrary hierarchy of groups.

EXPANDED indicates that, by default, the group should show up as
"expanded", so that the user immediately sees all of the components
within the group.  Otherwise, the group will initially show up as a
single entry.

BOLD_TITLE indicates that the group title should appear in bold, to
call the user's attention to the group.

Add installation type
"""""""""""""""""""""

.. command:: cpack_add_install_type

Add a new installation type containing
a set of predefined component selections to the graphical installer.

::

  cpack_add_install_type(typename
                         [DISPLAY_NAME name])

The cpack_add_install_type command identifies a set of preselected
components that represents a common use case for an application.  For
example, a "Developer" install type might include an application along
with its header and library files, while an "End user" install type
might just include the application's executable.  Each component
identifies itself with one or more install types via the INSTALL_TYPES
argument to cpack_add_component.

DISPLAY_NAME is the displayed name of the install type, which will
typically show up in a drop-down box within a graphical installer.
This value can be any string.

Configure downloads
"""""""""""""""""""

.. command:: cpack_configure_downloads

Configure CPack to download
selected components on-the-fly as part of the installation process.

::

  cpack_configure_downloads(site
                            [UPLOAD_DIRECTORY dirname]
                            [ALL]
                            [ADD_REMOVE|NO_ADD_REMOVE])

The cpack_configure_downloads command configures installation-time
downloads of selected components.  For each downloadable component,
CPack will create an archive containing the contents of that
component, which should be uploaded to the given site.  When the user
selects that component for installation, the installer will download
and extract the component in place.  This feature is useful for
creating small installers that only download the requested components,
saving bandwidth.  Additionally, the installers are small enough that
they will be installed as part of the normal installation process, and
the "Change" button in Windows Add/Remove Programs control panel will
allow one to add or remove parts of the application after the original
installation.  On Windows, the downloaded-components functionality
requires the ZipDLL plug-in for NSIS, available at:

::

  http://nsis.sourceforge.net/ZipDLL_plug-in

On macOS, installers that download components on-the-fly can only
be built and installed on system using macOS 10.5 or later.

The site argument is a URL where the archives for downloadable
components will reside, e.g.,
https://cmake.org/files/v3.25/ All of the archives
produced by CPack should be uploaded to that location.

UPLOAD_DIRECTORY is the local directory where CPack will create the
various archives for each of the components.  The contents of this
directory should be uploaded to a location accessible by the URL given
in the site argument.  If omitted, CPack will use the directory
CPackUploads inside the CMake binary directory to store the generated
archives.

The ALL flag indicates that all components be downloaded.  Otherwise,
only those components explicitly marked as DOWNLOADED or that have a
specified ARCHIVE_FILE will be downloaded.  Additionally, the ALL
option implies ADD_REMOVE (unless NO_ADD_REMOVE is specified).

ADD_REMOVE indicates that CPack should install a copy of the installer
that can be called from Windows' Add/Remove Programs dialog (via the
"Modify" button) to change the set of installed components.
NO_ADD_REMOVE turns off this behavior.  This option is ignored on Mac
OS X.
#]=======================================================================]

# Define var in order to avoid multiple inclusion
if(NOT CPackComponent_CMake_INCLUDED)
set(CPackComponent_CMake_INCLUDED 1)

# Function that appends a SET command for the given variable name (var)
# to the string named strvar, but only if the variable named "var"
# has been defined. The string will eventually be appended to a CPack
# configuration file.
function(cpack_append_variable_set_command var strvar)
  if (DEFINED ${var})
    string(APPEND ${strvar} "set(${var}")
    foreach(APPENDVAL ${${var}})
      string(APPEND ${strvar} " ${APPENDVAL}")
    endforeach()
    string(APPEND ${strvar} ")\n")
    set(${strvar} "${${strvar}}" PARENT_SCOPE)
  endif ()
endfunction()

# Function that appends a SET command for the given variable name (var)
# to the string named strvar, but only if the variable named "var"
# has been defined and is a string. The string will eventually be
# appended to a CPack configuration file.
function(cpack_append_string_variable_set_command var strvar)
  if (DEFINED ${var})
    list(LENGTH ${var} CPACK_APP_VALUE_LEN)
    if(${CPACK_APP_VALUE_LEN} EQUAL 1)
      string(APPEND ${strvar} "set(${var} \"${${var}}\")\n")
    endif()
    set(${strvar} "${${strvar}}" PARENT_SCOPE)
  endif ()
endfunction()

# Macro that appends a SET command for the given list variable name (var)
# to the macro named strvar, but only if the variable named "var"
# has been defined. It's like add variable, but wrap each item to quotes.
# The string will eventually be appended to a CPack configuration file.
macro(cpack_append_list_variable_set_command var strvar)
  if (DEFINED ${var})
    string(APPEND ${strvar} "set(${var}")
    foreach(_val IN LISTS ${var})
      string(APPEND ${strvar} "\n  \"${_val}\"")
    endforeach()
    string(APPEND ${strvar} ")\n")
  endif ()
endmacro()

# Macro that appends a SET command for the given variable name (var)
# to the macro named strvar, but only if the variable named "var"
# has been set to true. The string will eventually be
# appended to a CPack configuration file.
macro(cpack_append_option_set_command var strvar)
  if (${var})
    list(LENGTH ${var} CPACK_APP_VALUE_LEN)
    if(${CPACK_APP_VALUE_LEN} EQUAL 1)
      string(APPEND ${strvar} "set(${var} TRUE)\n")
    endif()
  endif ()
endmacro()

# Macro that adds a component to the CPack installer
macro(cpack_add_component compname)
  string(TOUPPER ${compname} _CPACK_ADDCOMP_UNAME)
  cmake_parse_arguments(CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}
    "HIDDEN;REQUIRED;DISABLED;DOWNLOADED"
    "DISPLAY_NAME;DESCRIPTION;GROUP;ARCHIVE_FILE;PLIST"
    "DEPENDS;INSTALL_TYPES"
    ${ARGN}
    )

  if (CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_DOWNLOADED)
    set(_CPACK_ADDCOMP_STR "\n# Configuration for downloaded component \"${compname}\"\n")
  else ()
    set(_CPACK_ADDCOMP_STR "\n# Configuration for component \"${compname}\"\n")
  endif ()

  if(NOT CPACK_MONOLITHIC_INSTALL)
    # If the user didn't set CPACK_COMPONENTS_ALL explicitly, update the
    # value of CPACK_COMPONENTS_ALL in the configuration file. This will
    # take care of any components that have been added after the CPack
    # moduled was included.
    if(NOT CPACK_COMPONENTS_ALL_SET_BY_USER)
      get_cmake_property(_CPACK_ADDCOMP_COMPONENTS COMPONENTS)
      string(APPEND _CPACK_ADDCOMP_STR "\nSET(CPACK_COMPONENTS_ALL")
      foreach(COMP ${_CPACK_ADDCOMP_COMPONENTS})
       string(APPEND _CPACK_ADDCOMP_STR " ${COMP}")
      endforeach()
      string(APPEND _CPACK_ADDCOMP_STR ")\n")
    endif()
  endif()

  cpack_append_string_variable_set_command(
    CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_DISPLAY_NAME
    _CPACK_ADDCOMP_STR)
  cpack_append_string_variable_set_command(
    CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_DESCRIPTION
    _CPACK_ADDCOMP_STR)
  cpack_append_variable_set_command(
    CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_GROUP
    _CPACK_ADDCOMP_STR)
  cpack_append_variable_set_command(
    CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_DEPENDS
    _CPACK_ADDCOMP_STR)
  cpack_append_variable_set_command(
    CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_INSTALL_TYPES
    _CPACK_ADDCOMP_STR)
  cpack_append_string_variable_set_command(
    CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_ARCHIVE_FILE
    _CPACK_ADDCOMP_STR)
  cpack_append_option_set_command(
    CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_HIDDEN
    _CPACK_ADDCOMP_STR)
  cpack_append_option_set_command(
    CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_REQUIRED
    _CPACK_ADDCOMP_STR)
  cpack_append_option_set_command(
    CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_DISABLED
    _CPACK_ADDCOMP_STR)
  cpack_append_option_set_command(
    CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_DOWNLOADED
    _CPACK_ADDCOMP_STR)
  cpack_append_string_variable_set_command(
    CPACK_COMPONENT_${_CPACK_ADDCOMP_UNAME}_PLIST
    _CPACK_ADDCOMP_STR)
  # Backward compatibility issue.
  # Write to config iff the macros is used after CPack.cmake has been
  # included, other it's not necessary because the variables
  # will be encoded by cpack_encode_variables.
  if(CPack_CMake_INCLUDED)
    file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_ADDCOMP_STR}")
  endif()
endmacro()

# Macro that adds a component group to the CPack installer
macro(cpack_add_component_group grpname)
  string(TOUPPER ${grpname} _CPACK_ADDGRP_UNAME)
  cmake_parse_arguments(CPACK_COMPONENT_GROUP_${_CPACK_ADDGRP_UNAME}
    "EXPANDED;BOLD_TITLE"
    "DISPLAY_NAME;DESCRIPTION;PARENT_GROUP"
    ""
    ${ARGN}
    )

  set(_CPACK_ADDGRP_STR "\n# Configuration for component group \"${grpname}\"\n")
  cpack_append_string_variable_set_command(
    CPACK_COMPONENT_GROUP_${_CPACK_ADDGRP_UNAME}_DISPLAY_NAME
    _CPACK_ADDGRP_STR)
  cpack_append_string_variable_set_command(
    CPACK_COMPONENT_GROUP_${_CPACK_ADDGRP_UNAME}_DESCRIPTION
    _CPACK_ADDGRP_STR)
  cpack_append_string_variable_set_command(
    CPACK_COMPONENT_GROUP_${_CPACK_ADDGRP_UNAME}_PARENT_GROUP
    _CPACK_ADDGRP_STR)
  cpack_append_option_set_command(
    CPACK_COMPONENT_GROUP_${_CPACK_ADDGRP_UNAME}_EXPANDED
    _CPACK_ADDGRP_STR)
  cpack_append_option_set_command(
    CPACK_COMPONENT_GROUP_${_CPACK_ADDGRP_UNAME}_BOLD_TITLE
    _CPACK_ADDGRP_STR)
  # Backward compatibility issue.
  # Write to config iff the macros is used after CPack.cmake has been
  # included, other it's not necessary because the variables
  # will be encoded by cpack_encode_variables.
  if(CPack_CMake_INCLUDED)
    file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_ADDGRP_STR}")
  endif()
endmacro()

# Macro that adds an installation type to the CPack installer
macro(cpack_add_install_type insttype)
  string(TOUPPER ${insttype} _CPACK_INSTTYPE_UNAME)
  cmake_parse_arguments(CPACK_INSTALL_TYPE_${_CPACK_INSTTYPE_UNAME}
    ""
    "DISPLAY_NAME"
    ""
    ${ARGN}
    )

  set(_CPACK_INSTTYPE_STR
    "\n# Configuration for installation type \"${insttype}\"\n")
  string(APPEND _CPACK_INSTTYPE_STR
    "list(APPEND CPACK_ALL_INSTALL_TYPES ${insttype})\n")
  cpack_append_string_variable_set_command(
    CPACK_INSTALL_TYPE_${_CPACK_INSTTYPE_UNAME}_DISPLAY_NAME
    _CPACK_INSTTYPE_STR)
  # Backward compatibility issue.
  # Write to config iff the macros is used after CPack.cmake has been
  # included, other it's not necessary because the variables
  # will be encoded by cpack_encode_variables.
  if(CPack_CMake_INCLUDED)
    file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_INSTTYPE_STR}")
  endif()
endmacro()

macro(cpack_configure_downloads site)
  cmake_parse_arguments(CPACK_DOWNLOAD
    "ALL;ADD_REMOVE;NO_ADD_REMOVE"
    "UPLOAD_DIRECTORY"
    ""
    ${ARGN}
    )

  set(CPACK_CONFIG_DL_STR
    "\n# Downloaded components configuration\n")
  set(CPACK_UPLOAD_DIRECTORY ${CPACK_DOWNLOAD_UPLOAD_DIRECTORY})
  set(CPACK_DOWNLOAD_SITE ${site})
  cpack_append_string_variable_set_command(
    CPACK_DOWNLOAD_SITE
    CPACK_CONFIG_DL_STR)
  cpack_append_string_variable_set_command(
    CPACK_UPLOAD_DIRECTORY
    CPACK_CONFIG_DL_STR)
  cpack_append_option_set_command(
    CPACK_DOWNLOAD_ALL
    CPACK_CONFIG_DL_STR)
  if (${CPACK_DOWNLOAD_ALL} AND NOT ${CPACK_DOWNLOAD_NO_ADD_REMOVE})
    set(CPACK_DOWNLOAD_ADD_REMOVE ON)
  endif ()
  set(CPACK_ADD_REMOVE ${CPACK_DOWNLOAD_ADD_REMOVE})
  cpack_append_option_set_command(
    CPACK_ADD_REMOVE
    CPACK_CONFIG_DL_STR)
  # Backward compatibility issue.
  # Write to config iff the macros is used after CPack.cmake has been
  # included, other it's not necessary because the variables
  # will be encoded by cpack_encode_variables.
  if(CPack_CMake_INCLUDED)
    file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${CPACK_CONFIG_DL_STR}")
  endif()
endmacro()
endif()


code:
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
CPackIFW
--------

.. versionadded:: 3.1

This module looks for the location of the command-line utilities supplied with the
`Qt Installer Framework <https://doc.qt.io/qtinstallerframework/index.html>`_
(QtIFW).

The module also defines several commands to control the behavior of the
:cpack_gen:`CPack IFW Generator`.

Commands
^^^^^^^^

The module defines the following commands:

.. command:: cpack_ifw_configure_component

  Sets the arguments specific to the CPack IFW generator.

  ::

    cpack_ifw_configure_component(<compname> [COMMON] [ESSENTIAL] [VIRTUAL]
                        [FORCED_INSTALLATION] [REQUIRES_ADMIN_RIGHTS]
                        [NAME <name>]
                        [DISPLAY_NAME <display_name>] # Note: Internationalization supported
                        [DESCRIPTION <description>] # Note: Internationalization supported
                        [UPDATE_TEXT <update_text>]
                        [VERSION <version>]
                        [RELEASE_DATE <release_date>]
                        [SCRIPT <script>]
                        [PRIORITY|SORTING_PRIORITY <sorting_priority>] # Note: PRIORITY is deprecated
                        [DEPENDS|DEPENDENCIES <com_id> ...]
                        [AUTO_DEPEND_ON <comp_id> ...]
                        [LICENSES <display_name> <file_path> ...]
                        [DEFAULT <value>]
                        [USER_INTERFACES <file_path> <file_path> ...]
                        [TRANSLATIONS <file_path> <file_path> ...]
                        [REPLACES <comp_id> ...]
                        [CHECKABLE <value>])

  This command should be called after :command:`cpack_add_component` command.

  ``COMMON``
    if set, then the component will be packaged and installed as part
    of a group to which it belongs.

  ``ESSENTIAL``
    .. versionadded:: 3.6

    if set, then the package manager stays disabled until that
    component is updated.

  ``VIRTUAL``
    .. versionadded:: 3.8

    if set, then the component will be hidden from the installer.
    It is a equivalent of the ``HIDDEN`` option from the
    :command:`cpack_add_component` command.

  ``FORCED_INSTALLATION``
    .. versionadded:: 3.8

    if set, then the component must always be installed.
    It is a equivalent of the ``REQUIRED`` option from the
    :command:`cpack_add_component` command.

  ``REQUIRES_ADMIN_RIGHTS``
    .. versionadded:: 3.8

    set it if the component needs to be installed with elevated permissions.

  ``NAME``
    is used to create domain-like identification for this component.
    By default used origin component name.

  ``DISPLAY_NAME``
    .. versionadded:: 3.8

    set to rewrite original name configured by
    :command:`cpack_add_component` command.

  ``DESCRIPTION``
    .. versionadded:: 3.8

    set to rewrite original description configured by
    :command:`cpack_add_component` command.

  ``UPDATE_TEXT``
    .. versionadded:: 3.8

    will be added to the component description if this is an update to
    the component.

  ``VERSION``
    is version of component.
    By default used :variable:`CPACK_PACKAGE_VERSION`.

  ``RELEASE_DATE``
    .. versionadded:: 3.8

    keep empty to auto generate.

  ``SCRIPT``
    is a relative or absolute path to operations script
    for this component.

  ``SORTING_PRIORITY``
    .. versionadded:: 3.8

    is priority of the component in the tree.

  ``PRIORITY``
    .. deprecated:: 3.8
      Old name for ``SORTING_PRIORITY``.

  ``DEPENDS``, ``DEPENDENCIES``
    .. versionadded:: 3.8

    list of dependency component or component group identifiers in
    QtIFW style.

    .. versionadded:: 3.21

    Component or group names listed as dependencies may contain hyphens.
    This requires QtIFW 3.1 or later.

  ``AUTO_DEPEND_ON``
    .. versionadded:: 3.8

    list of identifiers of component or component group in QtIFW style
    that this component has an automatic dependency on.

  ``LICENSES``
    pair of <display_name> and <file_path> of license text for this
    component. You can specify more then one license.

  ``DEFAULT``
    .. versionadded:: 3.8

    Possible values are: TRUE, FALSE, and SCRIPT.
    Set to FALSE to disable the component in the installer or to SCRIPT
    to resolved during runtime (don't forget add the file of the script
    as a value of the ``SCRIPT`` option).

  ``USER_INTERFACES``
    .. versionadded:: 3.7

    is a list of <file_path> ('.ui' files) representing pages to load.

  ``TRANSLATIONS``
    .. versionadded:: 3.8

    is a list of <file_path> ('.qm' files) representing translations to load.

  ``REPLACES``
    .. versionadded:: 3.10

    list of identifiers of component or component group to replace.

  ``CHECKABLE``
    .. versionadded:: 3.10

    Possible values are: TRUE, FALSE.
    Set to FALSE if you want to hide the checkbox for an item.
    This is useful when only a few subcomponents should be selected
    instead of all.

.. command:: cpack_ifw_configure_component_group

  Sets the arguments specific to the CPack IFW generator.

  ::

    cpack_ifw_configure_component_group(<groupname> [VIRTUAL]
                        [FORCED_INSTALLATION] [REQUIRES_ADMIN_RIGHTS]
                        [NAME <name>]
                        [DISPLAY_NAME <display_name>] # Note: Internationalization supported
                        [DESCRIPTION <description>] # Note: Internationalization supported
                        [UPDATE_TEXT <update_text>]
                        [VERSION <version>]
                        [RELEASE_DATE <release_date>]
                        [SCRIPT <script>]
                        [PRIORITY|SORTING_PRIORITY <sorting_priority>] # Note: PRIORITY is deprecated
                        [DEPENDS|DEPENDENCIES <com_id> ...]
                        [AUTO_DEPEND_ON <comp_id> ...]
                        [LICENSES <display_name> <file_path> ...]
                        [DEFAULT <value>]
                        [USER_INTERFACES <file_path> <file_path> ...]
                        [TRANSLATIONS <file_path> <file_path> ...]
                        [REPLACES <comp_id> ...]
                        [CHECKABLE <value>])

  This command should be called after :command:`cpack_add_component_group`
  command.

  ``VIRTUAL``
    .. versionadded:: 3.8

    if set, then the group will be hidden from the installer.
    Note that setting this on a root component does not work.

  ``FORCED_INSTALLATION``
    .. versionadded:: 3.8

    if set, then the group must always be installed.

  ``REQUIRES_ADMIN_RIGHTS``
    .. versionadded:: 3.8

    set it if the component group needs to be installed with elevated
    permissions.

  ``NAME``
    is used to create domain-like identification for this component group.
    By default used origin component group name.

  ``DISPLAY_NAME``
    .. versionadded:: 3.8

    set to rewrite original name configured by
    :command:`cpack_add_component_group` command.

  ``DESCRIPTION``
    .. versionadded:: 3.8

    set to rewrite original description configured by
    :command:`cpack_add_component_group` command.

  ``UPDATE_TEXT``
    .. versionadded:: 3.8

    will be added to the component group description if this is an update to
    the component group.

  ``VERSION``
    is version of component group.
    By default used :variable:`CPACK_PACKAGE_VERSION`.

  ``RELEASE_DATE``
    .. versionadded:: 3.8

    keep empty to auto generate.

  ``SCRIPT``
    is a relative or absolute path to operations script
    for this component group.

  ``SORTING_PRIORITY``
    is priority of the component group in the tree.

  ``PRIORITY``
    .. deprecated:: 3.8
      Old name for ``SORTING_PRIORITY``.

  ``DEPENDS``, ``DEPENDENCIES``
    .. versionadded:: 3.8

    list of dependency component or component group identifiers in
    QtIFW style.

    .. versionadded:: 3.21

    Component or group names listed as dependencies may contain hyphens.
    This requires QtIFW 3.1 or later.

  ``AUTO_DEPEND_ON``
    .. versionadded:: 3.8

    list of identifiers of component or component group in QtIFW style
    that this component group has an automatic dependency on.

  ``LICENSES``
    pair of <display_name> and <file_path> of license text for this
    component group. You can specify more then one license.

  ``DEFAULT``
    .. versionadded:: 3.8

    Possible values are: TRUE, FALSE, and SCRIPT.
    Set to TRUE to preselect the group in the installer
    (this takes effect only on groups that have no visible child components)
    or to SCRIPT to resolved during runtime (don't forget add the file of
    the script as a value of the ``SCRIPT`` option).

  ``USER_INTERFACES``
    .. versionadded:: 3.7

    is a list of <file_path> ('.ui' files) representing pages to load.

  ``TRANSLATIONS``
    .. versionadded:: 3.8

    is a list of <file_path> ('.qm' files) representing translations to load.

  ``REPLACES``
    .. versionadded:: 3.10

    list of identifiers of component or component group to replace.

  ``CHECKABLE``
    .. versionadded:: 3.10

    Possible values are: TRUE, FALSE.
    Set to FALSE if you want to hide the checkbox for an item.
    This is useful when only a few subcomponents should be selected
    instead of all.

.. command:: cpack_ifw_add_repository

  Add QtIFW specific remote repository to binary installer.

  ::

    cpack_ifw_add_repository(<reponame> [DISABLED]
                        URL <url>
                        [USERNAME <username>]
                        [PASSWORD <password>]
                        [DISPLAY_NAME <display_name>])

  This command will also add the <reponame> repository
  to a variable :variable:`CPACK_IFW_REPOSITORIES_ALL`.

  ``DISABLED``
    if set, then the repository will be disabled by default.

  ``URL``
    is points to a list of available components.

  ``USERNAME``
    is used as user on a protected repository.

  ``PASSWORD``
    is password to use on a protected repository.

  ``DISPLAY_NAME``
    is string to display instead of the URL.

.. command:: cpack_ifw_update_repository

  .. versionadded:: 3.6

  Update QtIFW specific repository from remote repository.

  ::

    cpack_ifw_update_repository(<reponame>
                        [[ADD|REMOVE] URL <url>]|
                         [REPLACE OLD_URL <old_url> NEW_URL <new_url>]]
                        [USERNAME <username>]
                        [PASSWORD <password>]
                        [DISPLAY_NAME <display_name>])

  This command will also add the <reponame> repository
  to a variable :variable:`CPACK_IFW_REPOSITORIES_ALL`.

  ``URL``
    is points to a list of available components.

  ``OLD_URL``
    is points to a list that will replaced.

  ``NEW_URL``
    is points to a list that will replace to.

  ``USERNAME``
    is used as user on a protected repository.

  ``PASSWORD``
    is password to use on a protected repository.

  ``DISPLAY_NAME``
    is string to display instead of the URL.

.. command:: cpack_ifw_add_package_resources

  .. versionadded:: 3.7

  Add additional resources in the installer binary.

  ::

    cpack_ifw_add_package_resources(<file_path> <file_path> ...)

  This command will also add the specified files
  to a variable :variable:`CPACK_IFW_PACKAGE_RESOURCES`.

#]=======================================================================]

# TODO:
# All of the internal implementation CMake modules for other CPack generators
# have been moved into the Internal/CPack directory. This one has not, because
# it contains user-facing macros which would be lost if it were moved. At some
# point, this module should be split into user-facing macros (which would live
# in this module) and internal implementation details (which would live in
# Internal/CPack/CPackIFW.cmake).

#=============================================================================
# Search Qt Installer Framework tools
#=============================================================================

# Default path

foreach(_CPACK_IFW_PATH_VAR "CPACK_IFW_ROOT" "QTIFWDIR" "QTDIR")
  if(DEFINED ${_CPACK_IFW_PATH_VAR}
    AND NOT "${${_CPACK_IFW_PATH_VAR}}" STREQUAL "")
    list(APPEND _CPACK_IFW_PATHS "${${_CPACK_IFW_PATH_VAR}}")
  endif()
  if(NOT "$ENV{${_CPACK_IFW_PATH_VAR}}" STREQUAL "")
    list(APPEND _CPACK_IFW_PATHS "$ENV{${_CPACK_IFW_PATH_VAR}}")
  endif()
endforeach()
if(WIN32)
  list(APPEND _CPACK_IFW_PATHS
    "$ENV{HOMEDRIVE}/Qt"
    "C:/Qt")
else()
  list(APPEND _CPACK_IFW_PATHS
    "$ENV{HOME}/Qt"
    "/opt/Qt")
endif()
list(REMOVE_DUPLICATES _CPACK_IFW_PATHS)

set(_CPACK_IFW_PREFIXES
  # QtSDK
  "Tools/QtInstallerFramework/"
  # Second branch
  "QtIFW"
  # First branch
  "QtIFW-")

set(_CPACK_IFW_VERSIONS
  "4.5.0"
  "4.5"
  "4.4.2"
  "4.4.1"
  "4.4.0"
  "4.4"
  "4.3.0"
  "4.3"
  "4.2.0"
  "4.2"
  "4.1.1"
  "4.1.0"
  "4.1"
  "4.0.1"
  "4.0.0"
  "4.0"
  "3.2.3"
  "3.2.2"
  "3.2.1"
  "3.2.0"
  "3.2"
  "3.1.1"
  "3.1.0"
  "3.1"
  "3.0.6"
  "3.0.4"
  "3.0.3"
  "3.0.2"
  "3.0.1"
  "3.0.0"
  "3.0"
  "2.3.0"
  "2.3"
  "2.2.0"
  "2.2"
  "2.1.0"
  "2.1"
  "2.0.5"
  "2.0.3"
  "2.0.2"
  "2.0.1"
  "2.0.0"
  "2.0"
  "1.6.0"
  "1.6"
  "1.5.0"
  "1.5"
  "1.4.0"
  "1.4"
  "1.3.0"
  "1.3")

set(_CPACK_IFW_SUFFIXES "bin")
foreach(_CPACK_IFW_PREFIX ${_CPACK_IFW_PREFIXES})
  foreach(_CPACK_IFW_VERSION ${_CPACK_IFW_VERSIONS})
    list(APPEND
      _CPACK_IFW_SUFFIXES "${_CPACK_IFW_PREFIX}${_CPACK_IFW_VERSION}/bin")
  endforeach()
endforeach()

# Look for 'binarycreator'

find_program(CPACK_IFW_BINARYCREATOR_EXECUTABLE
  NAMES binarycreator
  PATHS ${_CPACK_IFW_PATHS}
  PATH_SUFFIXES ${_CPACK_IFW_SUFFIXES}
  DOC "QtIFW binarycreator command line client")

mark_as_advanced(CPACK_IFW_BINARYCREATOR_EXECUTABLE)

# Look for 'repogen'

find_program(CPACK_IFW_REPOGEN_EXECUTABLE
  NAMES repogen
  PATHS ${_CPACK_IFW_PATHS}
  PATH_SUFFIXES ${_CPACK_IFW_SUFFIXES}
  DOC "QtIFW repogen command line client"
  )
mark_as_advanced(CPACK_IFW_REPOGEN_EXECUTABLE)

# Look for 'installerbase'

find_program(CPACK_IFW_INSTALLERBASE_EXECUTABLE
  NAMES installerbase
  PATHS ${_CPACK_IFW_PATHS}
  PATH_SUFFIXES ${_CPACK_IFW_SUFFIXES}
  DOC "QtIFW installer executable base"
  )
mark_as_advanced(CPACK_IFW_INSTALLERBASE_EXECUTABLE)

# Look for 'devtool' (appeared in the second branch)

find_program(CPACK_IFW_DEVTOOL_EXECUTABLE
  NAMES devtool
  PATHS ${_CPACK_IFW_PATHS}
  PATH_SUFFIXES ${_CPACK_IFW_SUFFIXES}
  DOC "QtIFW devtool command line client"
  )
mark_as_advanced(CPACK_IFW_DEVTOOL_EXECUTABLE)

# Look for 'archivegen'

find_program(CPACK_IFW_ARCHIVEGEN_EXECUTABLE
  NAMES archivegen
  PATHS ${_CPACK_IFW_PATHS}
  PATH_SUFFIXES ${_CPACK_IFW_SUFFIXES}
  DOC "QtIFW archivegen command line client"
  )
mark_as_advanced(CPACK_IFW_ARCHIVEGEN_EXECUTABLE)

#
## Next code is included only once
#

if(NOT CPackIFW_CMake_INCLUDED)
set(CPackIFW_CMake_INCLUDED 1)

#=============================================================================
# Framework version
#=============================================================================

set(CPACK_IFW_FRAMEWORK_VERSION_FORCED ""
  CACHE STRING "The forced version of used QtIFW tools")
mark_as_advanced(CPACK_IFW_FRAMEWORK_VERSION_FORCED)
set(CPACK_IFW_FRAMEWORK_VERSION_TIMEOUT 1
  CACHE STRING "The timeout to return QtIFW framework version string from \"installerbase\" executable")
mark_as_advanced(CPACK_IFW_FRAMEWORK_VERSION_TIMEOUT)
if(CPACK_IFW_INSTALLERBASE_EXECUTABLE AND NOT CPACK_IFW_FRAMEWORK_VERSION_FORCED)
  set(CPACK_IFW_FRAMEWORK_VERSION)
  # Invoke version from "installerbase" executable
  foreach(_ifw_version_argument --version --framework-version)
    if(NOT CPACK_IFW_FRAMEWORK_VERSION)
      execute_process(COMMAND
        "${CPACK_IFW_INSTALLERBASE_EXECUTABLE}" ${_ifw_version_argument}
        TIMEOUT ${CPACK_IFW_FRAMEWORK_VERSION_TIMEOUT}
        RESULT_VARIABLE CPACK_IFW_FRAMEWORK_VERSION_RESULT
        OUTPUT_VARIABLE CPACK_IFW_FRAMEWORK_VERSION_OUTPUT
        OUTPUT_STRIP_TRAILING_WHITESPACE
        ENCODING UTF8)
      if(NOT CPACK_IFW_FRAMEWORK_VERSION_RESULT AND CPACK_IFW_FRAMEWORK_VERSION_OUTPUT)
        string(REGEX MATCH "[0-9]+(\\.[0-9]+)*"
          CPACK_IFW_FRAMEWORK_VERSION "${CPACK_IFW_FRAMEWORK_VERSION_OUTPUT}")
        if(CPACK_IFW_FRAMEWORK_VERSION)
          if("${_ifw_version_argument}" STREQUAL "--framework-version")
            set(CPACK_IFW_FRAMEWORK_VERSION_SOURCE "INSTALLERBASE_FRAMEWORK_VERSION")
          elseif("${_ifw_version_argument}" STREQUAL "--version")
            set(CPACK_IFW_FRAMEWORK_VERSION_SOURCE "INSTALLERBASE_FRAMEWORK_VERSION")
          endif()
        endif()
      endif()
    endif()
  endforeach()
  # Finally try to get version from executable path
  if(NOT CPACK_IFW_FRAMEWORK_VERSION)
    string(REGEX MATCH "[0-9]+(\\.[0-9]+)*"
      CPACK_IFW_FRAMEWORK_VERSION "${CPACK_IFW_INSTALLERBASE_EXECUTABLE}")
    if(CPACK_IFW_FRAMEWORK_VERSION)
      set(CPACK_IFW_FRAMEWORK_VERSION_SOURCE "INSTALLERBASE_PATH")
    endif()
  endif()
elseif(CPACK_IFW_FRAMEWORK_VERSION_FORCED)
  set(CPACK_IFW_FRAMEWORK_VERSION ${CPACK_IFW_FRAMEWORK_VERSION_FORCED})
  set(CPACK_IFW_FRAMEWORK_VERSION_SOURCE "FORCED")
endif()
if(CPACK_IFW_VERBOSE)
  if(CPACK_IFW_FRAMEWORK_VERSION AND CPACK_IFW_FRAMEWORK_VERSION_FORCED)
    message(STATUS "Found QtIFW ${CPACK_IFW_FRAMEWORK_VERSION} (forced) version")
  elseif(CPACK_IFW_FRAMEWORK_VERSION)
    message(STATUS "Found QtIFW ${CPACK_IFW_FRAMEWORK_VERSION} version")
  endif()
endif()
if(CPACK_IFW_INSTALLERBASE_EXECUTABLE AND NOT CPACK_IFW_FRAMEWORK_VERSION)
  message(WARNING "Could not detect QtIFW tools version. Set used version to variable \"CPACK_IFW_FRAMEWORK_VERSION_FORCED\" manually.")
endif()

#=============================================================================
# Macro definition
#=============================================================================

# Macro definition based on CPackComponent

if(NOT CPackComponent_CMake_INCLUDED)
    include(CPackComponent)
endif()

# Resolve full filename for script file
macro(_cpack_ifw_resolve_script _variable)
  set(_ifw_script_macro ${_variable})
  set(_ifw_script_file ${${_ifw_script_macro}})
  if(DEFINED ${_ifw_script_macro})
    get_filename_component(${_ifw_script_macro} ${_ifw_script_file} ABSOLUTE)
    set(_ifw_script_file ${${_ifw_script_macro}})
    if(NOT EXISTS ${_ifw_script_file})
      message(WARNING "CPack IFW: script file \"${_ifw_script_file}\" does not exist")
      set(${_ifw_script_macro})
    endif()
  endif()
endmacro()

# Resolve full path to license file
macro(_cpack_ifw_resolve_lisenses _variable)
  if(${_variable})
    set(_ifw_license_file FALSE)
    set(_ifw_licenses_fix)
    foreach(_ifw_licenses_arg ${${_variable}})
      if(_ifw_license_file)
        get_filename_component(_ifw_licenses_arg "${_ifw_licenses_arg}" ABSOLUTE)
        set(_ifw_license_file FALSE)
      else()
        set(_ifw_license_file TRUE)
      endif()
      list(APPEND _ifw_licenses_fix "${_ifw_licenses_arg}")
    endforeach(_ifw_licenses_arg)
    set(${_variable} "${_ifw_licenses_fix}")
  endif()
endmacro()

# Resolve full path to a list of provided files
macro(_cpack_ifw_resolve_file_list _variable)
  if(${_variable})
    set(_ifw_list_fix)
    foreach(_ifw_file_arg ${${_variable}})
      get_filename_component(_ifw_file_arg "${_ifw_file_arg}" ABSOLUTE)
      if(EXISTS ${_ifw_file_arg})
        list(APPEND _ifw_list_fix "${_ifw_file_arg}")
      else()
        message(WARNING "CPack IFW: page file \"${_ifw_file_arg}\" does not exist. Skipping")
      endif()
    endforeach(_ifw_file_arg)
    set(${_variable} "${_ifw_list_fix}")
  endif()
endmacro()

# Macro for configure component
macro(cpack_ifw_configure_component compname)

  string(TOUPPER ${compname} _CPACK_IFWCOMP_UNAME)

  set(_IFW_OPT COMMON ESSENTIAL VIRTUAL FORCED_INSTALLATION REQUIRES_ADMIN_RIGHTS)
  set(_IFW_ARGS NAME VERSION RELEASE_DATE SCRIPT PRIORITY SORTING_PRIORITY UPDATE_TEXT DEFAULT CHECKABLE)
  set(_IFW_MULTI_ARGS DISPLAY_NAME DESCRIPTION DEPENDS DEPENDENCIES AUTO_DEPEND_ON LICENSES USER_INTERFACES TRANSLATIONS REPLACES)
  cmake_parse_arguments(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})

  _cpack_ifw_resolve_script(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_SCRIPT)
  _cpack_ifw_resolve_lisenses(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_LICENSES)
  _cpack_ifw_resolve_file_list(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_USER_INTERFACES)
  _cpack_ifw_resolve_file_list(CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_TRANSLATIONS)

  set(_CPACK_IFWCOMP_STR "\n# Configuration for IFW component \"${compname}\"\n")

  foreach(_IFW_ARG_NAME ${_IFW_OPT})
  cpack_append_option_set_command(
    CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_${_IFW_ARG_NAME}
    _CPACK_IFWCOMP_STR)
  endforeach()

  foreach(_IFW_ARG_NAME ${_IFW_ARGS})
  cpack_append_string_variable_set_command(
    CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_${_IFW_ARG_NAME}
    _CPACK_IFWCOMP_STR)
  endforeach()

  foreach(_IFW_ARG_NAME ${_IFW_MULTI_ARGS})
  cpack_append_list_variable_set_command(
    CPACK_IFW_COMPONENT_${_CPACK_IFWCOMP_UNAME}_${_IFW_ARG_NAME}
    _CPACK_IFWCOMP_STR)
  endforeach()

  if(CPack_CMake_INCLUDED)
    file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_IFWCOMP_STR}")
  endif()

endmacro()

# Macro for configure group
macro(cpack_ifw_configure_component_group grpname)

  string(TOUPPER ${grpname} _CPACK_IFWGRP_UNAME)

  set(_IFW_OPT VIRTUAL FORCED_INSTALLATION REQUIRES_ADMIN_RIGHTS)
  set(_IFW_ARGS NAME VERSION RELEASE_DATE SCRIPT PRIORITY SORTING_PRIORITY UPDATE_TEXT DEFAULT CHECKABLE)
  set(_IFW_MULTI_ARGS DISPLAY_NAME DESCRIPTION DEPENDS DEPENDENCIES AUTO_DEPEND_ON LICENSES USER_INTERFACES TRANSLATIONS REPLACES)
  cmake_parse_arguments(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})

  _cpack_ifw_resolve_script(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_SCRIPT)
  _cpack_ifw_resolve_lisenses(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_LICENSES)
  _cpack_ifw_resolve_file_list(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_USER_INTERFACES)
  _cpack_ifw_resolve_file_list(CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_TRANSLATIONS)

  set(_CPACK_IFWGRP_STR "\n# Configuration for IFW component group \"${grpname}\"\n")

  foreach(_IFW_ARG_NAME ${_IFW_OPT})
  cpack_append_option_set_command(
    CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_${_IFW_ARG_NAME}
    _CPACK_IFWGRP_STR)
  endforeach()

  foreach(_IFW_ARG_NAME ${_IFW_ARGS})
  cpack_append_string_variable_set_command(
    CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_${_IFW_ARG_NAME}
    _CPACK_IFWGRP_STR)
  endforeach()

  foreach(_IFW_ARG_NAME ${_IFW_MULTI_ARGS})
  cpack_append_list_variable_set_command(
    CPACK_IFW_COMPONENT_GROUP_${_CPACK_IFWGRP_UNAME}_${_IFW_ARG_NAME}
    _CPACK_IFWGRP_STR)
  endforeach()

  if(CPack_CMake_INCLUDED)
    file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_IFWGRP_STR}")
  endif()
endmacro()

# Macro for adding repository
macro(cpack_ifw_add_repository reponame)

  string(TOUPPER ${reponame} _CPACK_IFWREPO_UNAME)

  set(_IFW_OPT DISABLED)
  set(_IFW_ARGS URL USERNAME PASSWORD DISPLAY_NAME)
  set(_IFW_MULTI_ARGS)
  cmake_parse_arguments(CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})

  set(_CPACK_IFWREPO_STR "\n# Configuration for IFW repository \"${reponame}\"\n")

  foreach(_IFW_ARG_NAME ${_IFW_OPT})
  cpack_append_option_set_command(
    CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_${_IFW_ARG_NAME}
    _CPACK_IFWREPO_STR)
  endforeach()

  foreach(_IFW_ARG_NAME ${_IFW_ARGS})
  cpack_append_string_variable_set_command(
    CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_${_IFW_ARG_NAME}
    _CPACK_IFWREPO_STR)
  endforeach()

  foreach(_IFW_ARG_NAME ${_IFW_MULTI_ARGS})
  cpack_append_variable_set_command(
    CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_${_IFW_ARG_NAME}
    _CPACK_IFWREPO_STR)
  endforeach()

  list(APPEND CPACK_IFW_REPOSITORIES_ALL ${reponame})
  string(APPEND _CPACK_IFWREPO_STR "list(APPEND CPACK_IFW_REPOSITORIES_ALL ${reponame})\n")

  if(CPack_CMake_INCLUDED)
    file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_IFWREPO_STR}")
  endif()

endmacro()

# Macro for updating repository
macro(cpack_ifw_update_repository reponame)

  string(TOUPPER ${reponame} _CPACK_IFWREPO_UNAME)

  set(_IFW_OPT ADD REMOVE REPLACE DISABLED)
  set(_IFW_ARGS URL OLD_URL NEW_URL USERNAME PASSWORD DISPLAY_NAME)
  set(_IFW_MULTI_ARGS)
  cmake_parse_arguments(CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME} "${_IFW_OPT}" "${_IFW_ARGS}" "${_IFW_MULTI_ARGS}" ${ARGN})

  set(_CPACK_IFWREPO_STR "\n# Configuration for IFW repository \"${reponame}\" update\n")

  foreach(_IFW_ARG_NAME ${_IFW_OPT})
  cpack_append_option_set_command(
    CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_${_IFW_ARG_NAME}
    _CPACK_IFWREPO_STR)
  endforeach()

  foreach(_IFW_ARG_NAME ${_IFW_ARGS})
  cpack_append_string_variable_set_command(
    CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_${_IFW_ARG_NAME}
    _CPACK_IFWREPO_STR)
  endforeach()

  foreach(_IFW_ARG_NAME ${_IFW_MULTI_ARGS})
  cpack_append_variable_set_command(
    CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_${_IFW_ARG_NAME}
    _CPACK_IFWREPO_STR)
  endforeach()

  if(CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_ADD
    OR CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_REMOVE
    OR CPACK_IFW_REPOSITORY_${_CPACK_IFWREPO_UNAME}_REPLACE)
    list(APPEND CPACK_IFW_REPOSITORIES_ALL ${reponame})
    string(APPEND _CPACK_IFWREPO_STR "list(APPEND CPACK_IFW_REPOSITORIES_ALL ${reponame})\n")
  else()
    set(_CPACK_IFWREPO_STR)
  endif()

  if(CPack_CMake_INCLUDED AND _CPACK_IFWREPO_STR)
    file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_IFWREPO_STR}")
  endif()

endmacro()

# Macro for adding resources
macro(cpack_ifw_add_package_resources)
  set(_CPACK_IFW_PACKAGE_RESOURCES ${ARGV})
  _cpack_ifw_resolve_file_list(_CPACK_IFW_PACKAGE_RESOURCES)
  list(APPEND CPACK_IFW_PACKAGE_RESOURCES ${_CPACK_IFW_PACKAGE_RESOURCES})
  set(_CPACK_IFWQRC_STR "list(APPEND CPACK_IFW_PACKAGE_RESOURCES \"${_CPACK_IFW_PACKAGE_RESOURCES}\")\n")
  if(CPack_CMake_INCLUDED)
    file(APPEND "${CPACK_OUTPUT_CONFIG_FILE}" "${_CPACK_IFWQRC_STR}")
  endif()
endmacro()

# Resolve package control script
_cpack_ifw_resolve_script(CPACK_IFW_PACKAGE_CONTROL_SCRIPT)

endif() # NOT CPackIFW_CMake_INCLUDED

repo_name: lazytadpole/codenamesilverfish

license: mit


code:
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
CPackIFWConfigureFile
---------------------

.. versionadded:: 3.8

The module defines :command:`configure_file` similar command to
configure file templates prepared in QtIFW/SDK/Creator style.

Commands
^^^^^^^^

The module defines the following commands:

.. command:: cpack_ifw_configure_file

  Copy a file to another location and modify its contents.

  ::

    cpack_ifw_configure_file(<input> <output>)

  Copies an ``<input>`` file to an ``<output>`` file and substitutes variable
  values referenced as ``%{VAR}`` or ``%VAR%`` in the input file content.
  Each variable reference will be replaced with the current value of the
  variable, or the empty string if the variable is not defined.

#]=======================================================================]

# NOTE: This file used to himself packaging via CPack IFW generator and
# should be compatible with minimal CMake version defined in
# ../CMakeLists.txt file.

if(NOT DEFINED CPackIFWConfigureFile_CMake_INCLUDED)
set(CPackIFWConfigureFile_CMake_INCLUDED 1)

macro(cpack_ifw_configure_file INPUT OUTPUT)
  file(READ "${INPUT}" _tmp)
  foreach(_tmp_regex "%{([^%}]+)}" "%([^%]+)%")
    string(REGEX MATCHALL "${_tmp_regex}" _tmp_vars "${_tmp}")
    while(_tmp_vars)
      foreach(_tmp_var ${_tmp_vars})
        string(REGEX REPLACE "${_tmp_regex}" "\\1"
          _tmp_var_name "${_tmp_var}")
        if(DEFINED ${_tmp_var_name})
          set(_tmp_var_value "${${_tmp_var_name}}")
        elseif(NOT "$ENV{${_tmp_var_name}}" STREQUAL "")
          set(_tmp_var_value "$ENV{${_tmp_var_name}}")
        else()
          set(_tmp_var_value "")
        endif()
        string(REPLACE "${_tmp_var}" "${_tmp_var_value}" _tmp "${_tmp}")
      endforeach()
      string(REGEX MATCHALL "${_tmp_regex}" _tmp_vars "${_tmp}")
    endwhile()
  endforeach()
  if(IS_ABSOLUTE "${OUTPUT}")
    file(WRITE "${OUTPUT}" "${_tmp}")
  else()
    file(WRITE "${CMAKE_CURRENT_BINARY_DIR}/${OUTPUT}" "${_tmp}")
  endif()
endmacro()

endif() # NOT DEFINED CPackIFWConfigureFile_CMake_INCLUDED


code:
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
CSharpUtilities
---------------

.. versionadded:: 3.8

Functions to make configuration of CSharp/.NET targets easier.

A collection of CMake utility functions useful for dealing with CSharp
targets for Visual Studio generators from version 2010 and later.

The following functions are provided by this module:

**Main functions**

- :command:`csharp_set_windows_forms_properties`
- :command:`csharp_set_designer_cs_properties`
- :command:`csharp_set_xaml_cs_properties`

**Helper functions**

- :command:`csharp_get_filename_keys`
- :command:`csharp_get_filename_key_base`
- :command:`csharp_get_dependentupon_name`

Main functions provided by the module
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. command:: csharp_set_windows_forms_properties

  Sets source file properties for use of Windows Forms. Use this, if your CSharp
  target uses Windows Forms::

    csharp_set_windows_forms_properties([<file1> [<file2> [...]]])

  ``<fileN>``
    List of all source files which are relevant for setting the
    :prop_sf:`VS_CSHARP_<tagname>` properties (including ``.cs``, ``.resx`` and
    ``.Designer.cs`` extensions).

  In the list of all given files for all files ending with ``.Designer.cs`` and
  ``.resx`` is searched.  For every *designer* or *resource* file a file with the
  same base name but only ``.cs`` as extension is searched.  If this is found, the
  :prop_sf:`VS_CSHARP_<tagname>` properties are set as follows:

  for the **.cs** file:
   - VS_CSHARP_SubType "Form"

  for the **.Designer.cs** file (if it exists):
   - VS_CSHARP_DependentUpon <cs-filename>
   - VS_CSHARP_DesignTime "" (delete tag if previously defined)
   - VS_CSHARP_AutoGen ""(delete tag if previously defined)

  for the **.resx** file (if it exists):
   - VS_RESOURCE_GENERATOR "" (delete tag if previously defined)
   - VS_CSHARP_DependentUpon <cs-filename>
   - VS_CSHARP_SubType "Designer"

.. command:: csharp_set_designer_cs_properties

  Sets source file properties of ``.Designer.cs`` files depending on
  sibling filenames. Use this, if your CSharp target does **not**
  use Windows Forms (for Windows Forms use
  :command:`csharp_set_windows_forms_properties` instead)::

    csharp_set_designer_cs_properties([<file1> [<file2> [...]]])

  ``<fileN>``
    List of all source files which are relevant for setting the
    :prop_sf:`VS_CSHARP_<tagname>` properties (including ``.cs``,
    ``.resx``, ``.settings`` and ``.Designer.cs`` extensions).

  In the list of all given files for all files ending with
  ``.Designer.cs`` is searched. For every *designer* file all files
  with the same base name but different extensions are searched. If
  a match is found, the source file properties of the *designer* file
  are set depending on the extension of the matched file:

  if match is **.resx** file:
   - VS_CSHARP_AutoGen "True"
   - VS_CSHARP_DesignTime "True"
   - VS_CSHARP_DependentUpon <resx-filename>

  if match is **.cs** file:
   - VS_CSHARP_DependentUpon <cs-filename>

  if match is **.settings** file:
   - VS_CSHARP_AutoGen "True"
   - VS_CSHARP_DesignTimeSharedInput "True"
   - VS_CSHARP_DependentUpon <settings-filename>

.. note::

    Because the source file properties of the ``.Designer.cs`` file are set according
    to the found matches and every match sets the **VS_CSHARP_DependentUpon**
    property, there should only be one match for each ``Designer.cs`` file.

.. command:: csharp_set_xaml_cs_properties

  Sets source file properties for use of Windows Presentation Foundation (WPF) and
  XAML. Use this, if your CSharp target uses WPF/XAML::

    csharp_set_xaml_cs_properties([<file1> [<file2> [...]]])

  ``<fileN>``
    List of all source files which are relevant for setting the
    :prop_sf:`VS_CSHARP_<tagname>` properties (including ``.cs``,
    ``.xaml``, and ``.xaml.cs`` extensions).

  In the list of all given files for all files ending with
  ``.xaml.cs`` is searched. For every *xaml-cs* file, a file
  with the same base name but extension ``.xaml`` is searched.
  If a match is found, the source file properties of the ``.xaml.cs``
  file are set:

   - VS_CSHARP_DependentUpon <xaml-filename>

Helper functions which are used by the above ones
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

.. command:: csharp_get_filename_keys

  Helper function which computes a list of key values to identify
  source files independently of relative/absolute paths given in cmake
  and eliminates case sensitivity::

    csharp_get_filename_keys(OUT [<file1> [<file2> [...]]])

  ``OUT``
    Name of the variable in which the list of keys is stored

  ``<fileN>``
    filename(s) as given to to CSharp target using :command:`add_library`
    or :command:`add_executable`

  In some way the function applies a canonicalization to the source names.
  This is necessary to find file matches if the files have been added to
  the target with different directory prefixes:

  .. code-block:: cmake

    add_library(lib
      myfile.cs
      ${CMAKE_CURRENT_SOURCE_DIR}/myfile.Designer.cs)

    set_source_files_properties(myfile.Designer.cs PROPERTIES
      VS_CSHARP_DependentUpon myfile.cs)

    # this will fail, because in cmake
    #  - ${CMAKE_CURRENT_SOURCE_DIR}/myfile.Designer.cs
    #  - myfile.Designer.cs
    # are not the same source file. The source file property is not set.

.. command:: csharp_get_filename_key_base

  Returns the full filepath and name **without** extension of a key.
  KEY is expected to be a key from csharp_get_filename_keys. In BASE
  the value of KEY without the file extension is returned::

    csharp_get_filename_key_base(BASE KEY)

  ``BASE``
    Name of the variable with the computed "base" of ``KEY``.

  ``KEY``
    The key of which the base will be computed. Expected to be a
    upper case full filename.

.. command:: csharp_get_dependentupon_name

  Computes a string which can be used as value for the source file property
  :prop_sf:`VS_CSHARP_<tagname>` with *target* being ``DependentUpon``::

    csharp_get_dependentupon_name(NAME FILE)

  ``NAME``
    Name of the variable with the result value

  ``FILE``
    Filename to convert to ``<DependentUpon>`` value

  Actually this is only the filename without any path given at the moment.

#]=======================================================================]

cmake_policy(PUSH)
cmake_policy(SET CMP0057 NEW) # if IN_LIST

function(csharp_get_filename_keys OUT)
  set(${OUT} "")
  foreach(f ${ARGN})
    get_filename_component(f ${f} REALPATH)
    string(TOUPPER ${f} f)
    list(APPEND ${OUT} ${f})
  endforeach()
  set(${OUT} "${${OUT}}" PARENT_SCOPE)
endfunction()

function(csharp_get_filename_key_base base key)
  get_filename_component(dir ${key} DIRECTORY)
  get_filename_component(fil ${key} NAME_WE)
  set(${base} "${dir}/${fil}" PARENT_SCOPE)
endfunction()

function(csharp_get_dependentupon_name out in)
  get_filename_component(${out} ${in} NAME)
  set(${out} ${${out}} PARENT_SCOPE)
endfunction()

function(csharp_set_windows_forms_properties)
  csharp_get_filename_keys(fileKeys ${ARGN})
  foreach(key ${fileKeys})
    get_filename_component(ext ${key} EXT)
    if(${ext} STREQUAL ".DESIGNER.CS" OR
       ${ext} STREQUAL ".RESX")
      csharp_get_filename_key_base(NAME_BASE ${key})
      list(FIND fileKeys "${NAME_BASE}.CS" FILE_INDEX)
      if(NOT ${FILE_INDEX} EQUAL -1)
        list(GET ARGN ${FILE_INDEX} FILE_NAME)
        # set properties of main form file
        set_source_files_properties("${FILE_NAME}"
          PROPERTIES
          VS_CSHARP_SubType "Form")
        csharp_get_dependentupon_name(LINK "${FILE_NAME}")
        # set properties of designer file (if found)
        list(FIND fileKeys "${NAME_BASE}.DESIGNER.CS" FILE_INDEX)
        if(NOT ${FILE_INDEX} EQUAL -1)
          list(GET ARGN ${FILE_INDEX} FILE_NAME)
          set_source_files_properties("${FILE_NAME}"
            PROPERTIES
            VS_CSHARP_DependentUpon "${LINK}"
            VS_CSHARP_DesignTime ""
            VS_CSHARP_AutoGen "")
        endif()
        # set properties of corresponding resource file (if found)
        list(FIND fileKeys "${NAME_BASE}.RESX" FILE_INDEX)
        if(NOT ${FILE_INDEX} EQUAL -1)
          list(GET ARGN ${FILE_INDEX} FILE_NAME)
          set_source_files_properties("${FILE_NAME}"
            PROPERTIES
            VS_RESOURCE_GENERATOR ""
            VS_CSHARP_DependentUpon "${LINK}"
            VS_CSHARP_SubType "Designer")
        endif()
      endif()
    endif()
  endforeach()
endfunction()

function(csharp_set_designer_cs_properties)
  csharp_get_filename_keys(fileKeys ${ARGN})
  set(INDEX -1)
  foreach(key ${fileKeys})
    math(EXPR INDEX "${INDEX}+1")
    list(GET ARGN ${INDEX} source)
    get_filename_component(ext ${key} EXT)
    if(${ext} STREQUAL ".DESIGNER.CS")
      csharp_get_filename_key_base(NAME_BASE ${key})
      if("${NAME_BASE}.RESX" IN_LIST fileKeys)
        list(FIND fileKeys "${NAME_BASE}.RESX" FILE_INDEX)
        list(GET ARGN ${FILE_INDEX} FILE_NAME)
        csharp_get_dependentupon_name(LINK "${FILE_NAME}")
        set_source_files_properties("${source}"
          PROPERTIES
          VS_CSHARP_AutoGen "True"
          VS_CSHARP_DesignTime "True"
          VS_CSHARP_DependentUpon "${LINK}")
      elseif("${NAME_BASE}.CS" IN_LIST fileKeys)
        list(FIND fileKeys "${NAME_BASE}.CS" FILE_INDEX)
        list(GET ARGN ${FILE_INDEX} FILE_NAME)
        csharp_get_dependentupon_name(LINK "${FILE_NAME}")
        set_source_files_properties("${source}"
          PROPERTIES
          VS_CSHARP_DependentUpon "${LINK}")
      elseif("${NAME_BASE}.SETTINGS" IN_LIST fileKeys)
        list(FIND fileKeys "${NAME_BASE}.SETTINGS" FILE_INDEX)
        list(GET ARGN ${FILE_INDEX} FILE_NAME)
        csharp_get_dependentupon_name(LINK "${FILE_NAME}")
        set_source_files_properties("${source}"
          PROPERTIES
          VS_CSHARP_AutoGen "True"
          VS_CSHARP_DesignTimeSharedInput "True"
          VS_CSHARP_DependentUpon "${LINK}")
      endif()
    endif()
  endforeach()
endfunction()

function(csharp_set_xaml_cs_properties)
  csharp_get_filename_keys(fileKeys ${ARGN})
  set(INDEX -1)
  foreach(key ${fileKeys})
    math(EXPR INDEX "${INDEX}+1")
    list(GET ARGN ${INDEX} source)
    get_filename_component(ext ${key} EXT)
    if(${ext} STREQUAL ".XAML.CS")
      csharp_get_filename_key_base(NAME_BASE ${key})
      if("${NAME_BASE}.XAML" IN_LIST fileKeys)
        list(FIND fileKeys "${NAME_BASE}.XAML" FILE_INDEX)
        list(GET ARGN ${FILE_INDEX} FILE_NAME)
        csharp_get_dependentupon_name(LINK "${FILE_NAME}")
        set_source_files_properties("${source}"
          PROPERTIES
          VS_CSHARP_DependentUpon "${LINK}")
      endif()
    endif()
  endforeach()
endfunction()

cmake_policy(POP)


code:
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
CTest
-----

Configure a project for testing with CTest/CDash

Include this module in the top CMakeLists.txt file of a project to
enable testing with CTest and dashboard submissions to CDash::

  project(MyProject)
  ...
  include(CTest)

The module automatically creates a ``BUILD_TESTING`` option that selects
whether to enable testing support (``ON`` by default).  After including
the module, use code like::

  if(BUILD_TESTING)
    # ... CMake code to create tests ...
  endif()

to creating tests when testing is enabled.

To enable submissions to a CDash server, create a ``CTestConfig.cmake``
file at the top of the project with content such as::

  set(CTEST_NIGHTLY_START_TIME "01:00:00 UTC")
  set(CTEST_SUBMIT_URL "http://my.cdash.org/submit.php?project=MyProject")

(the CDash server can provide the file to a project administrator who
configures ``MyProject``).  Settings in the config file are shared by
both this ``CTest`` module and the :manual:`ctest(1)` command-line
:ref:`Dashboard Client` mode (:option:`ctest -S`).

While building a project for submission to CDash, CTest scans the
build output for errors and warnings and reports them with surrounding
context from the build log.  This generic approach works for all build
tools, but does not give details about the command invocation that
produced a given problem.  One may get more detailed reports by setting
the :variable:`CTEST_USE_LAUNCHERS` variable::

  set(CTEST_USE_LAUNCHERS 1)

in the ``CTestConfig.cmake`` file.
#]=======================================================================]

option(BUILD_TESTING "Build the testing tree." ON)

# function to turn generator name into a version string
# like vs9 or vs10
function(GET_VS_VERSION_STRING generator var)
  string(REGEX REPLACE "Visual Studio ([0-9][0-9]?)($|.*)" "\\1"
    NUMBER "${generator}")
    set(ver_string "vs${NUMBER}")
  set(${var} ${ver_string} PARENT_SCOPE)
endfunction()

include(CTestUseLaunchers)

if(BUILD_TESTING)
  # Setup some auxiliary macros
  macro(SET_IF_NOT_SET var val)
    if(NOT DEFINED "${var}")
      set("${var}" "${val}")
    endif()
  endmacro()

  macro(SET_IF_SET var val)
    if(NOT "${val}" STREQUAL "")
      set("${var}" "${val}")
    endif()
  endmacro()

  macro(SET_IF_SET_AND_NOT_SET var val)
    if(NOT "${val}" STREQUAL "")
      SET_IF_NOT_SET("${var}" "${val}")
    endif()
  endmacro()

  # Make sure testing is enabled
  enable_testing()

  if(EXISTS "${PROJECT_SOURCE_DIR}/CTestConfig.cmake")
    include("${PROJECT_SOURCE_DIR}/CTestConfig.cmake")
    SET_IF_SET_AND_NOT_SET(NIGHTLY_START_TIME "${CTEST_NIGHTLY_START_TIME}")
    SET_IF_SET_AND_NOT_SET(SUBMIT_URL "${CTEST_SUBMIT_URL}")
    SET_IF_SET_AND_NOT_SET(DROP_METHOD "${CTEST_DROP_METHOD}")
    SET_IF_SET_AND_NOT_SET(DROP_SITE "${CTEST_DROP_SITE}")
    SET_IF_SET_AND_NOT_SET(DROP_SITE_USER "${CTEST_DROP_SITE_USER}")
    SET_IF_SET_AND_NOT_SET(DROP_SITE_PASSWORD "${CTEST_DROP_SITE_PASWORD}")
    SET_IF_SET_AND_NOT_SET(DROP_SITE_MODE "${CTEST_DROP_SITE_MODE}")
    SET_IF_SET_AND_NOT_SET(DROP_LOCATION "${CTEST_DROP_LOCATION}")
    SET_IF_SET_AND_NOT_SET(TRIGGER_SITE "${CTEST_TRIGGER_SITE}")
    SET_IF_SET_AND_NOT_SET(UPDATE_TYPE "${CTEST_UPDATE_TYPE}")
  endif()

  # the project can have a DartConfig.cmake file
  if(EXISTS "${PROJECT_SOURCE_DIR}/DartConfig.cmake")
    include("${PROJECT_SOURCE_DIR}/DartConfig.cmake")
  else()
    # Dashboard is opened for submissions for a 24 hour period starting at
    # the specified NIGHTLY_START_TIME. Time is specified in 24 hour format.
    SET_IF_NOT_SET (NIGHTLY_START_TIME "00:00:00 EDT")
    SET_IF_NOT_SET(DROP_METHOD "http")
    SET_IF_NOT_SET (COMPRESS_SUBMISSION ON)
  endif()
  SET_IF_NOT_SET (NIGHTLY_START_TIME "00:00:00 EDT")

  if(NOT SUBMIT_URL)
    set(SUBMIT_URL "${DROP_METHOD}://")
    if(DROP_SITE_USER)
      string(APPEND SUBMIT_URL "${DROP_SITE_USER}")
      if(DROP_SITE_PASSWORD)
        string(APPEND SUBMIT_URL ":${DROP_SITE_PASSWORD}")
      endif()
      string(APPEND SUBMIT_URL "@")
    endif()
    string(APPEND SUBMIT_URL "${DROP_SITE}${DROP_LOCATION}")
  endif()

  if(NOT UPDATE_TYPE)
    if(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/CVS")
      set(UPDATE_TYPE cvs)
    elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.svn")
      set(UPDATE_TYPE svn)
    elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.bzr")
      set(UPDATE_TYPE bzr)
    elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.hg")
      set(UPDATE_TYPE hg)
    elseif(EXISTS "${CMAKE_CURRENT_SOURCE_DIR}/.git")
      set(UPDATE_TYPE git)
    endif()
  endif()

  string(TOLOWER "${UPDATE_TYPE}" _update_type)
  if("${_update_type}" STREQUAL "cvs")
    find_program(CVSCOMMAND cvs )
    set(CVS_UPDATE_OPTIONS "-d -A -P" CACHE STRING
      "Options passed to the cvs update command.")
    set(UPDATE_COMMAND "${CVSCOMMAND}")
    set(UPDATE_OPTIONS "${CVS_UPDATE_OPTIONS}")
  elseif("${_update_type}" STREQUAL "svn")
    find_program(SVNCOMMAND svn)
    set(UPDATE_COMMAND "${SVNCOMMAND}")
    set(UPDATE_OPTIONS "${SVN_UPDATE_OPTIONS}")
  elseif("${_update_type}" STREQUAL "bzr")
    find_program(BZRCOMMAND bzr)
    set(UPDATE_COMMAND "${BZRCOMMAND}")
    set(UPDATE_OPTIONS "${BZR_UPDATE_OPTIONS}")
  elseif("${_update_type}" STREQUAL "hg")
    find_program(HGCOMMAND hg)
    set(UPDATE_COMMAND "${HGCOMMAND}")
    set(UPDATE_OPTIONS "${HG_UPDATE_OPTIONS}")
  elseif("${_update_type}" STREQUAL "git")
    find_program(GITCOMMAND git)
    set(UPDATE_COMMAND "${GITCOMMAND}")
    set(UPDATE_OPTIONS "${GIT_UPDATE_OPTIONS}")
  elseif("${_update_type}" STREQUAL "p4")
    find_program(P4COMMAND p4)
    set(UPDATE_COMMAND "${P4COMMAND}")
    set(UPDATE_OPTIONS "${P4_UPDATE_OPTIONS}")
  endif()

  set(DART_TESTING_TIMEOUT 1500 CACHE STRING
    "Maximum time allowed before CTest will kill the test.")

  set(CTEST_SUBMIT_RETRY_DELAY 5 CACHE STRING
    "How long to wait between timed-out CTest submissions.")
  set(CTEST_SUBMIT_RETRY_COUNT 3 CACHE STRING
    "How many times to retry timed-out CTest submissions.")

  find_program(MEMORYCHECK_COMMAND
    NAMES purify valgrind boundscheck drmemory cuda-memcheck compute-sanitizer
    PATHS
    "[HKEY_LOCAL_MACHINE\\SOFTWARE\\Rational Software\\Purify\\Setup;InstallFolder]"
    DOC "Path to the memory checking command, used for memory error detection."
    )
  set(MEMORYCHECK_SUPPRESSIONS_FILE "" CACHE FILEPATH
    "File that contains suppressions for the memory checker")
  find_program(COVERAGE_COMMAND gcov DOC
    "Path to the coverage program that CTest uses for performing coverage inspection"
    )
  set(COVERAGE_EXTRA_FLAGS "-l" CACHE STRING
    "Extra command line flags to pass to the coverage tool")

  # set the site name
  if(COMMAND cmake_host_system_information)
    cmake_host_system_information(RESULT _ctest_hostname QUERY HOSTNAME)
    set(SITE "${_ctest_hostname}" CACHE STRING "Name of the computer/site where compile is being run")
    unset(_ctest_hostname)
  else()
    # This code path is needed for CMake itself during bootstrap.
    site_name(SITE)
  endif()
  # set the build name
  if(NOT BUILDNAME)
    set(DART_COMPILER "${CMAKE_CXX_COMPILER}")
    if(NOT DART_COMPILER)
      set(DART_COMPILER "${CMAKE_C_COMPILER}")
    endif()
    if(NOT DART_COMPILER)
      set(DART_COMPILER "unknown")
    endif()
    if(WIN32)
      set(DART_NAME_COMPONENT "NAME_WE")
    else()
      set(DART_NAME_COMPONENT "NAME")
    endif()
    if(NOT BUILD_NAME_SYSTEM_NAME)
      set(BUILD_NAME_SYSTEM_NAME "${CMAKE_SYSTEM_NAME}")
    endif()
    if(WIN32)
      set(BUILD_NAME_SYSTEM_NAME "Win32")
    endif()
    if(UNIX OR BORLAND)
      get_filename_component(DART_COMPILER_NAME
        "${DART_COMPILER}" ${DART_NAME_COMPONENT})
    else()
      get_filename_component(DART_COMPILER_NAME
        "${CMAKE_MAKE_PROGRAM}" ${DART_NAME_COMPONENT})
    endif()
    if(DART_COMPILER_NAME MATCHES "devenv")
      GET_VS_VERSION_STRING("${CMAKE_GENERATOR}" DART_COMPILER_NAME)
    endif()
    set(BUILDNAME "${BUILD_NAME_SYSTEM_NAME}-${DART_COMPILER_NAME}")
  endif()

  # the build command
  build_command(MAKECOMMAND_DEFAULT_VALUE
    CONFIGURATION "\${CTEST_CONFIGURATION_TYPE}")
  set(MAKECOMMAND ${MAKECOMMAND_DEFAULT_VALUE}
    CACHE STRING "Command to build the project")

  # the default build configuration the ctest build handler will use
  # if there is no -C arg given to ctest:
  set(DEFAULT_CTEST_CONFIGURATION_TYPE "$ENV{CMAKE_CONFIG_TYPE}")
  if(DEFAULT_CTEST_CONFIGURATION_TYPE STREQUAL "")
    set(DEFAULT_CTEST_CONFIGURATION_TYPE "Release")
  endif()

  mark_as_advanced(
    BZRCOMMAND
    COVERAGE_COMMAND
    COVERAGE_EXTRA_FLAGS
    CTEST_SUBMIT_RETRY_DELAY
    CTEST_SUBMIT_RETRY_COUNT
    CVSCOMMAND
    CVS_UPDATE_OPTIONS
    DART_TESTING_TIMEOUT
    GITCOMMAND
    P4COMMAND
    HGCOMMAND
    MAKECOMMAND
    MEMORYCHECK_COMMAND
    MEMORYCHECK_SUPPRESSIONS_FILE
    SITE
    SVNCOMMAND
    )
  if(NOT RUN_FROM_DART)
    set(RUN_FROM_CTEST_OR_DART 1)
    include(CTestTargets)
    set(RUN_FROM_CTEST_OR_DART)
  endif()
endif()


code:
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
CTestCoverageCollectGCOV
------------------------

.. versionadded:: 3.2

This module provides the ``ctest_coverage_collect_gcov`` function.

This function runs gcov on all .gcda files found in the binary tree
and packages the resulting .gcov files into a tar file.
This tarball also contains the following:

* *data.json* defines the source and build directories for use by CDash.
* *Labels.json* indicates any :prop_sf:`LABELS` that have been set on the
  source files.
* The *uncovered* directory holds any uncovered files found by
  :variable:`CTEST_EXTRA_COVERAGE_GLOB`.

After generating this tar file, it can be sent to CDash for display with the
:command:`ctest_submit(CDASH_UPLOAD)` command.

.. command:: ctest_coverage_collect_gcov

  ::

    ctest_coverage_collect_gcov(TARBALL <tarfile>
      [SOURCE <source_dir>][BUILD <build_dir>]
      [GCOV_COMMAND <gcov_command>]
      [GCOV_OPTIONS <options>...]
      )

  Run gcov and package a tar file for CDash.  The options are:

  ``TARBALL <tarfile>``
    Specify the location of the ``.tar`` file to be created for later
    upload to CDash.  Relative paths will be interpreted with respect
    to the top-level build directory.

  ``TARBALL_COMPRESSION <option>``
    .. versionadded:: 3.18

    Specify a compression algorithm for the
    ``TARBALL`` data file.  Using this option reduces the size of the data file
    before it is submitted to CDash.  ``<option>`` must be one of ``GZIP``,
    ``BZIP2``, ``XZ``, ``ZSTD``, ``FROM_EXT``, or an expression that CMake
    evaluates as ``FALSE``. The default value is ``BZIP2``.

    If ``FROM_EXT`` is specified, the resulting file will be compressed based on
    the file extension of the ``<tarfile>`` (i.e. ``.tar.gz`` will use ``GZIP``
    compression). File extensions that will produce compressed output include
    ``.tar.gz``, ``.tgz``, ``.tar.bzip2``, ``.tbz``, ``.tar.xz``, and ``.txz``.

  ``SOURCE <source_dir>``
    Specify the top-level source directory for the build.
    Default is the value of :variable:`CTEST_SOURCE_DIRECTORY`.

  ``BUILD <build_dir>``
    Specify the top-level build directory for the build.
    Default is the value of :variable:`CTEST_BINARY_DIRECTORY`.

  ``GCOV_COMMAND <gcov_command>``
    Specify the full path to the ``gcov`` command on the machine.
    Default is the value of :variable:`CTEST_COVERAGE_COMMAND`.

  ``GCOV_OPTIONS <options>...``
    Specify options to be passed to gcov.  The ``gcov`` command
    is run as ``gcov <options>... -o <gcov-dir> <file>.gcda``.
    If not specified, the default option is just ``-b -x``.

  ``GLOB``
    .. versionadded:: 3.6

    Recursively search for .gcda files in build_dir rather than
    determining search locations by reading TargetDirectories.txt.

  ``DELETE``
    .. versionadded:: 3.6

    Delete coverage files after they've been packaged into the .tar.

  ``QUIET``
    Suppress non-error messages that otherwise would have been
    printed out by this function.

  .. versionadded:: 3.3
    Added support for the :variable:`CTEST_CUSTOM_COVERAGE_EXCLUDE` variable.

#]=======================================================================]

function(ctest_coverage_collect_gcov)
  set(options QUIET GLOB DELETE)
  set(oneValueArgs TARBALL SOURCE BUILD GCOV_COMMAND TARBALL_COMPRESSION)
  set(multiValueArgs GCOV_OPTIONS)
  cmake_parse_arguments(GCOV  "${options}" "${oneValueArgs}"
    "${multiValueArgs}" "" ${ARGN} )
  if(NOT DEFINED GCOV_TARBALL)
    message(FATAL_ERROR
      "TARBALL must be specified. for ctest_coverage_collect_gcov")
  endif()
  if(NOT DEFINED GCOV_SOURCE)
    set(source_dir "${CTEST_SOURCE_DIRECTORY}")
  else()
    set(source_dir "${GCOV_SOURCE}")
  endif()
  if(NOT DEFINED GCOV_BUILD)
    set(binary_dir "${CTEST_BINARY_DIRECTORY}")
  else()
    set(binary_dir "${GCOV_BUILD}")
  endif()
  if(NOT DEFINED GCOV_GCOV_COMMAND)
    set(gcov_command "${CTEST_COVERAGE_COMMAND}")
  else()
    set(gcov_command "${GCOV_GCOV_COMMAND}")
  endif()
  if(NOT DEFINED GCOV_TARBALL_COMPRESSION)
    set(GCOV_TARBALL_COMPRESSION "BZIP2")
  elseif( GCOV_TARBALL_COMPRESSION AND
      NOT GCOV_TARBALL_COMPRESSION MATCHES "^(GZIP|BZIP2|XZ|ZSTD|FROM_EXT)$")
    message(FATAL_ERROR "TARBALL_COMPRESSION must be one of OFF, GZIP, "
      "BZIP2, XZ, ZSTD, or FROM_EXT for ctest_coverage_collect_gcov")
  endif()
  # run gcov on each gcda file in the binary tree
  set(gcda_files)
  set(label_files)
  if (GCOV_GLOB)
      file(GLOB_RECURSE gfiles "${binary_dir}/*.gcda")
      list(LENGTH gfiles len)
      # if we have gcda files then also grab the labels file for that target
      if(${len} GREATER 0)
        file(GLOB_RECURSE lfiles RELATIVE ${binary_dir} "${binary_dir}/Labels.json")
        list(APPEND gcda_files ${gfiles})
        list(APPEND label_files ${lfiles})
      endif()
  else()
    # look for gcda files in the target directories
    # this will be faster and only look where the files will be
    file(STRINGS "${binary_dir}/CMakeFiles/TargetDirectories.txt" target_dirs
         ENCODING UTF-8)
    foreach(target_dir ${target_dirs})
      file(GLOB_RECURSE gfiles "${target_dir}/*.gcda")
      list(LENGTH gfiles len)
      # if we have gcda files then also grab the labels file for that target
      if(${len} GREATER 0)
        file(GLOB_RECURSE lfiles RELATIVE ${binary_dir}
          "${target_dir}/Labels.json")
        list(APPEND gcda_files ${gfiles})
        list(APPEND label_files ${lfiles})
      endif()
    endforeach()
  endif()
  # return early if no coverage files were found
  list(LENGTH gcda_files len)
  if(len EQUAL 0)
    if (NOT GCOV_QUIET)
      message("ctest_coverage_collect_gcov: No .gcda files found, "
        "ignoring coverage request.")
    endif()
    return()
  endif()
  # setup the dir for the coverage files
  set(coverage_dir "${binary_dir}/Testing/CoverageInfo")
  file(MAKE_DIRECTORY  "${coverage_dir}")
  # run gcov, this will produce the .gcov files in the current
  # working directory
  if(NOT DEFINED GCOV_GCOV_OPTIONS)
    set(GCOV_GCOV_OPTIONS -b -x)
  endif()
  if (GCOV_QUIET)
    set(coverage_out_opts
      OUTPUT_QUIET
      ERROR_QUIET
      )
  else()
    set(coverage_out_opts
      OUTPUT_FILE "${coverage_dir}/gcov.log"
      ERROR_FILE  "${coverage_dir}/gcov.log"
      )
  endif()
  execute_process(COMMAND
    ${gcov_command} ${GCOV_GCOV_OPTIONS} ${gcda_files}
    RESULT_VARIABLE res
    WORKING_DIRECTORY ${coverage_dir}
    ${coverage_out_opts}
    )

  if (GCOV_DELETE)
    file(REMOVE ${gcda_files})
  endif()

  if(NOT "${res}" EQUAL 0)
    if (NOT GCOV_QUIET)
      message(STATUS "Error running gcov: ${res}, see\n  ${coverage_dir}/gcov.log")
    endif()
  endif()
  # create json file with project information
  file(WRITE ${coverage_dir}/data.json
    "{
    \"Source\": \"${source_dir}\",
    \"Binary\": \"${binary_dir}\"
}")
  # collect the gcov files
  set(unfiltered_gcov_files)
  file(GLOB_RECURSE unfiltered_gcov_files RELATIVE ${binary_dir} "${coverage_dir}/*.gcov")

  # if CTEST_EXTRA_COVERAGE_GLOB was specified we search for files
  # that might be uncovered
  if (DEFINED CTEST_EXTRA_COVERAGE_GLOB)
    set(uncovered_files)
    foreach(search_entry IN LISTS CTEST_EXTRA_COVERAGE_GLOB)
      if(NOT GCOV_QUIET)
        message("Add coverage glob: ${search_entry}")
      endif()
      file(GLOB_RECURSE matching_files "${source_dir}/${search_entry}")
      if (matching_files)
        list(APPEND uncovered_files "${matching_files}")
      endif()
    endforeach()
  endif()

  set(gcov_files)
  foreach(gcov_file ${unfiltered_gcov_files})
    file(STRINGS ${binary_dir}/${gcov_file} first_line LIMIT_COUNT 1 ENCODING UTF-8)

    set(is_excluded false)
    if(first_line MATCHES "^        -:    0:Source:(.*)$")
      set(source_file ${CMAKE_MATCH_1})
    elseif(NOT GCOV_QUIET)
      message(STATUS "Could not determine source file corresponding to: ${gcov_file}")
    endif()

    foreach(exclude_entry IN LISTS CTEST_CUSTOM_COVERAGE_EXCLUDE)
      if(source_file MATCHES "${exclude_entry}")
        set(is_excluded true)

        if(NOT GCOV_QUIET)
          message("Excluding coverage for: ${source_file} which matches ${exclude_entry}")
        endif()

        break()
      endif()
    endforeach()

    get_filename_component(resolved_source_file "${source_file}" ABSOLUTE)
    foreach(uncovered_file IN LISTS uncovered_files)
      get_filename_component(resolved_uncovered_file "${uncovered_file}" ABSOLUTE)
      if (resolved_uncovered_file STREQUAL resolved_source_file)
        list(REMOVE_ITEM uncovered_files "${uncovered_file}")
      endif()
    endforeach()

    if(NOT is_excluded)
      list(APPEND gcov_files ${gcov_file})
    endif()
  endforeach()

  foreach (uncovered_file ${uncovered_files})
    # Check if this uncovered file should be excluded.
    set(is_excluded false)
    foreach(exclude_entry IN LISTS CTEST_CUSTOM_COVERAGE_EXCLUDE)
      if(uncovered_file MATCHES "${exclude_entry}")
        set(is_excluded true)
        if(NOT GCOV_QUIET)
          message("Excluding coverage for: ${uncovered_file} which matches ${exclude_entry}")
        endif()
        break()
      endif()
    endforeach()
    if(is_excluded)
      continue()
    endif()

    # Copy from source to binary dir, preserving any intermediate subdirectories.
    get_filename_component(filename "${uncovered_file}" NAME)
    get_filename_component(relative_path "${uncovered_file}" DIRECTORY)
    string(REPLACE "${source_dir}" "" relative_path "${relative_path}")
    if (relative_path)
      # Strip leading slash.
      string(SUBSTRING "${relative_path}" 1 -1 relative_path)
    endif()
    file(COPY ${uncovered_file} DESTINATION ${binary_dir}/uncovered/${relative_path})
    if(relative_path)
      list(APPEND uncovered_files_for_tar uncovered/${relative_path}/${filename})
    else()
      list(APPEND uncovered_files_for_tar uncovered/${filename})
    endif()
  endforeach()

  # tar up the coverage info with the same date so that the md5
  # sum will be the same for the tar file independent of file time
  # stamps
  string(REPLACE ";" "\n" gcov_files "${gcov_files}")
  string(REPLACE ";" "\n" label_files "${label_files}")
  string(REPLACE ";" "\n" uncovered_files_for_tar "${uncovered_files_for_tar}")
  file(WRITE "${coverage_dir}/coverage_file_list.txt"
    "${gcov_files}
${coverage_dir}/data.json
${label_files}
${uncovered_files_for_tar}
")

  # Prepare tar command line arguments

  set(tar_opts "")
  # Select data compression mode
  if( GCOV_TARBALL_COMPRESSION STREQUAL "FROM_EXT")
    if( GCOV_TARBALL MATCHES [[\.(tgz|tar.gz)$]] )
      string(APPEND tar_opts "z")
    elseif( GCOV_TARBALL MATCHES [[\.(txz|tar.xz)$]] )
      string(APPEND tar_opts "J")
    elseif( GCOV_TARBALL MATCHES [[\.(tbz|tar.bz)$]] )
      string(APPEND tar_opts "j")
    endif()
  elseif(GCOV_TARBALL_COMPRESSION STREQUAL "GZIP")
    string(APPEND tar_opts "z")
  elseif(GCOV_TARBALL_COMPRESSION STREQUAL "XZ")
    string(APPEND tar_opts "J")
  elseif(GCOV_TARBALL_COMPRESSION STREQUAL "BZIP2")
    string(APPEND tar_opts "j")
  elseif(GCOV_TARBALL_COMPRESSION STREQUAL "ZSTD")
    set(zstd_tar_opt "--zstd")
  endif()
  # Verbosity options
  if(NOT GCOV_QUIET AND NOT tar_opts MATCHES v)
    string(APPEND tar_opts "v")
  endif()
  # Prepend option 'c' specifying 'create'
  string(PREPEND tar_opts "c")
  # Append option 'f' so that the next argument is the filename
  string(APPEND tar_opts "f")

  execute_process(COMMAND
    ${CMAKE_COMMAND} -E tar ${tar_opts} ${GCOV_TARBALL} ${zstd_tar_opt}
    "--mtime=1970-01-01 0:0:0 UTC"
    "--format=gnutar"
    --files-from=${coverage_dir}/coverage_file_list.txt
    WORKING_DIRECTORY ${binary_dir})

  if (GCOV_DELETE)
    foreach(gcov_file ${unfiltered_gcov_files})
      file(REMOVE ${binary_dir}/${gcov_file})
    endforeach()
    file(REMOVE ${coverage_dir}/coverage_file_list.txt)
    file(REMOVE ${coverage_dir}/data.json)
    if (EXISTS ${binary_dir}/uncovered)
      file(REMOVE ${binary_dir}/uncovered)
    endif()
  endif()

endfunction()


code:
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
CTestScriptMode
---------------

This file is read by ctest in script mode (-S)
#]=======================================================================]

# Determine the current system, so this information can be used
# in ctest scripts
include(CMakeDetermineSystem)

# Also load the system specific file, which sets up e.g. the search paths.
# This makes the FIND_XXX() calls work much better
include(CMakeSystemSpecificInformation)


code:
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

if(NOT RUN_FROM_CTEST_OR_DART)
  message(FATAL_ERROR "Do not include CTestTargets.cmake directly")
endif()

if(NOT PROJECT_BINARY_DIR)
  message(FATAL_ERROR "Do not include(CTest) before calling project().")
endif()

# make directories in the binary tree
file(MAKE_DIRECTORY ${PROJECT_BINARY_DIR}/Testing/Temporary)
get_filename_component(CMAKE_HOST_PATH ${CMAKE_COMMAND} PATH)
set(CMAKE_TARGET_PATH ${EXECUTABLE_OUTPUT_PATH})
find_program(CMAKE_CTEST_COMMAND ctest ${CMAKE_HOST_PATH} ${CMAKE_TARGET_PATH})
mark_as_advanced(CMAKE_CTEST_COMMAND)

# Use CTest
# configure files

if(CTEST_NEW_FORMAT)
  configure_file(
    ${CMAKE_ROOT}/Modules/DartConfiguration.tcl.in
    ${PROJECT_BINARY_DIR}/CTestConfiguration.ini )
else()
  configure_file(
    ${CMAKE_ROOT}/Modules/DartConfiguration.tcl.in
    ${PROJECT_BINARY_DIR}/DartConfiguration.tcl )
endif()

#
# Section 3:
#
# Custom targets to perform dashboard builds and submissions.
# These should NOT need to be modified from project to project.
#

set(__conf_types "")
get_property(_isMultiConfig GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
if(_isMultiConfig)
  # We need to pass the configuration type on the test command line.
  set(__conf_types -C "$<CONFIG>")
endif()

# Add convenience targets.  Do this at most once in case of nested
# projects.
define_property(GLOBAL PROPERTY CTEST_TARGETS_ADDED
  BRIEF_DOCS "Internal property used by CTestTargets module."
  FULL_DOCS "Set by the CTestTargets module to track addition of testing targets."
  )
get_property(_CTEST_TARGETS_ADDED GLOBAL PROPERTY CTEST_TARGETS_ADDED)
if(NOT _CTEST_TARGETS_ADDED)
  set_property(GLOBAL PROPERTY CTEST_TARGETS_ADDED 1)

  # For all generators add basic testing targets.
  foreach(mode Experimental Nightly Continuous NightlyMemoryCheck)
    add_custom_target(${mode}
      ${CMAKE_CTEST_COMMAND} ${__conf_types} -D ${mode}
      USES_TERMINAL
      )
    set_property(TARGET ${mode} PROPERTY RULE_LAUNCH_CUSTOM "")
    set_property(TARGET ${mode} PROPERTY FOLDER "CTestDashboardTargets")
  endforeach()

  # For Makefile generators add more granular targets.
  if("${CMAKE_GENERATOR}" MATCHES "(Ninja|Make)")
    # Make targets for Experimental builds
    foreach(mode Nightly Experimental Continuous)
      foreach(testtype
          Start Update Configure Build Test Coverage MemCheck Submit
          # missing purify
          )
        add_custom_target(${mode}${testtype}
          ${CMAKE_CTEST_COMMAND} ${__conf_types} -D ${mode}${testtype}
          USES_TERMINAL
          )
        set_property(TARGET ${mode}${testtype} PROPERTY RULE_LAUNCH_CUSTOM "")
        set_property(TARGET ${mode}${testtype} PROPERTY FOLDER "CTestDashboardTargets")
      endforeach()
    endforeach()
  endif()

  # If requested, add an alias that is the equivalent of the built-in "test"
  # or "RUN_TESTS" target:
  if(CTEST_TEST_TARGET_ALIAS)
    add_custom_target(${CTEST_TEST_TARGET_ALIAS}
      ${CMAKE_CTEST_COMMAND} ${CMAKE_CTEST_ARGUMENTS} ${__conf_types}
      USES_TERMINAL
      )
  endif()
endif()


code:
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
CTestUseLaunchers
-----------------

Set the RULE_LAUNCH_* global properties when CTEST_USE_LAUNCHERS is on.

CTestUseLaunchers is automatically included when you include(CTest).
However, it is split out into its own module file so projects can use
the CTEST_USE_LAUNCHERS functionality independently.

To use launchers, set CTEST_USE_LAUNCHERS to ON in a :option:`ctest -S`
dashboard script, and then also set it in the cache of the configured
project.  Both cmake and ctest need to know the value of it for the
launchers to work properly.  CMake needs to know in order to generate
proper build rules, and ctest, in order to produce the proper error
and warning analysis.

For convenience, you may set the ENV variable
CTEST_USE_LAUNCHERS_DEFAULT in your ctest -S script, too.  Then, as
long as your CMakeLists uses include(CTest) or
include(CTestUseLaunchers), it will use the value of the ENV variable
to initialize a CTEST_USE_LAUNCHERS cache variable.  This cache
variable initialization only occurs if CTEST_USE_LAUNCHERS is not
already defined.

.. versionadded:: 3.8
  If CTEST_USE_LAUNCHERS is on in a :option:`ctest -S` script
  the ctest_configure command will add -DCTEST_USE_LAUNCHERS:BOOL=TRUE
  to the cmake command used to configure the project.

.. TODO Use RST markup

#]=======================================================================]

if(NOT DEFINED CTEST_USE_LAUNCHERS AND DEFINED ENV{CTEST_USE_LAUNCHERS_DEFAULT})
  set(CTEST_USE_LAUNCHERS "$ENV{CTEST_USE_LAUNCHERS_DEFAULT}"
    CACHE INTERNAL "CTEST_USE_LAUNCHERS initial value from ENV")
endif()

if(NOT "${CMAKE_GENERATOR}" MATCHES "Make|Ninja")
  set(CTEST_USE_LAUNCHERS 0)
endif()

if(CTEST_USE_LAUNCHERS)
  set(__launch_common_options
    "--target-name <TARGET_NAME> --build-dir <CMAKE_CURRENT_BINARY_DIR>")

  set(__launch_compile_options
    "${__launch_common_options} --output <OBJECT> --source <SOURCE> --language <LANGUAGE>")

  set(__launch_link_options
    "${__launch_common_options} --output <TARGET> --target-type <TARGET_TYPE> --language <LANGUAGE>")

  set(__launch_custom_options
    "${__launch_common_options} --output <OUTPUT>")

  if("${CMAKE_GENERATOR}" MATCHES "Ninja")
    string(APPEND __launch_compile_options " --filter-prefix <CMAKE_CL_SHOWINCLUDES_PREFIX>")
  endif()

  set(CTEST_LAUNCH_COMPILE
    "\"${CMAKE_CTEST_COMMAND}\" --launch ${__launch_compile_options} --")

  set(CTEST_LAUNCH_LINK
    "\"${CMAKE_CTEST_COMMAND}\" --launch ${__launch_link_options} --")

  set(CTEST_LAUNCH_CUSTOM
    "\"${CMAKE_CTEST_COMMAND}\" --launch ${__launch_custom_options} --")

  set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE "${CTEST_LAUNCH_COMPILE}")
  set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK "${CTEST_LAUNCH_LINK}")
  set_property(GLOBAL PROPERTY RULE_LAUNCH_CUSTOM "${CTEST_LAUNCH_CUSTOM}")
endif()


code:
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
CheckCCompilerFlag
------------------

Check whether the C compiler supports a given flag.

.. command:: check_c_compiler_flag

  .. code-block:: cmake

    check_c_compiler_flag(<flag> <resultVar>)

  Check that the ``<flag>`` is accepted by the compiler without
  a diagnostic.  Stores the result in an internal cache entry
  named ``<resultVar>``.

A positive result from this check indicates only that the compiler did not
issue a diagnostic message when given the flag.  Whether the flag has any
effect or even a specific one is beyond the scope of this module.

The check is only performed once, with the result cached in the variable named
by ``<resultVar>``. Every subsequent CMake run will reuse this cached value
rather than performing the check again, even if the ``<code>`` changes. In
order to force the check to be re-evaluated, the variable named by
``<resultVar>`` must be manually removed from the cache.

The compile and link commands can be influenced by setting any of the
following variables prior to calling ``check_c_compiler_flag()``

.. include:: /module/CMAKE_REQUIRED_FLAGS.txt

.. include:: /module/CMAKE_REQUIRED_DEFINITIONS.txt

.. include:: /module/CMAKE_REQUIRED_INCLUDES.txt

.. include:: /module/CMAKE_REQUIRED_LINK_OPTIONS.txt

.. include:: /module/CMAKE_REQUIRED_LIBRARIES.txt

.. include:: /module/CMAKE_REQUIRED_QUIET.txt

#]=======================================================================]

include_guard(GLOBAL)
include(Internal/CheckCompilerFlag)

macro (CHECK_C_COMPILER_FLAG _FLAG _RESULT)
  cmake_check_compiler_flag(C "${_FLAG}" ${_RESULT})
endmacro ()

# FIXME(#24994): The following module is included only for compatibility
# with projects that accidentally relied on it with CMake 3.26 and below.
include(CheckCSourceCompiles)


code:
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
CheckCSourceCompiles
--------------------

Check if given C source compiles and links into an executable.

.. command:: check_c_source_compiles

  .. code-block:: cmake

    check_c_source_compiles(<code> <resultVar>
                            [FAIL_REGEX <regex1> [<regex2>...]])

  Check that the source supplied in ``<code>`` can be compiled as a C source
  file and linked as an executable (so it must contain at least a ``main()``
  function). The result will be stored in the internal cache variable specified
  by ``<resultVar>``, with a boolean true value for success and boolean false
  for failure. If ``FAIL_REGEX`` is provided, then failure is determined by
  checking if anything in the output matches any of the specified regular
  expressions.

  The check is only performed once, with the result cached in the variable named
  by ``<resultVar>``. Every subsequent CMake run will reuse this cached value
  rather than performing the check again, even if the ``<code>`` changes. In
  order to force the check to be re-evaluated, the variable named by
  ``<resultVar>`` must be manually removed from the cache.

  The compile and link commands can be influenced by setting any of the
  following variables prior to calling ``check_c_source_compiles()``:

.. include:: /module/CMAKE_REQUIRED_FLAGS.txt

.. include:: /module/CMAKE_REQUIRED_DEFINITIONS.txt

.. include:: /module/CMAKE_REQUIRED_INCLUDES.txt

.. include:: /module/CMAKE_REQUIRED_LINK_OPTIONS.txt

.. include:: /module/CMAKE_REQUIRED_LIBRARIES.txt

.. include:: /module/CMAKE_REQUIRED_QUIET.txt

#]=======================================================================]

include_guard(GLOBAL)
include(Internal/CheckSourceCompiles)

macro(CHECK_C_SOURCE_COMPILES SOURCE VAR)
  cmake_check_source_compiles(C "${SOURCE}" ${VAR} ${ARGN})
endmacro()


code:
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
CheckCSourceRuns
----------------

Check if given C source compiles and links into an executable and can
subsequently be run.

.. command:: check_c_source_runs

  .. code-block:: cmake

    check_c_source_runs(<code> <resultVar>)

  Check that the source supplied in ``<code>`` can be compiled as a C source
  file, linked as an executable and then run. The ``<code>`` must contain at
  least a ``main()`` function. If the ``<code>`` could be built and run
  successfully, the internal cache variable specified by ``<resultVar>`` will
  be set to 1, otherwise it will be set to an value that evaluates to boolean
  false (e.g. an empty string or an error message).

  The check is only performed once, with the result cached in the variable named
  by ``<resultVar>``. Every subsequent CMake run will reuse this cached value
  rather than performing the check again, even if the ``<code>`` changes. In
  order to force the check to be re-evaluated, the variable named by
  ``<resultVar>`` must be manually removed from the cache.

  The compile and link commands can be influenced by setting any of the
  following variables prior to calling ``check_c_source_runs()``:

.. include:: /module/CMAKE_REQUIRED_FLAGS.txt

.. include:: /module/CMAKE_REQUIRED_DEFINITIONS.txt

.. include:: /module/CMAKE_REQUIRED_INCLUDES.txt

.. include:: /module/CMAKE_REQUIRED_LINK_OPTIONS.txt

.. include:: /module/CMAKE_REQUIRED_LIBRARIES.txt

.. include:: /module/CMAKE_REQUIRED_QUIET.txt

#]=======================================================================]

include_guard(GLOBAL)
include(Internal/CheckSourceRuns)

macro(CHECK_C_SOURCE_RUNS SOURCE VAR)
  set(_CheckSourceRuns_old_signature 1)
  cmake_check_source_runs(C "${SOURCE}" ${VAR} ${ARGN})
  unset(_CheckSourceRuns_old_signature)
endmacro()


code:
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
CheckCXXCompilerFlag
------------------------

Check whether the CXX compiler supports a given flag.

.. command:: check_cxx_compiler_flag

  .. code-block:: cmake

    check_cxx_compiler_flag(<flag> <var>)

  Check that the ``<flag>`` is accepted by the compiler without
  a diagnostic.  Stores the result in an internal cache entry
  named ``<var>``.

A positive result from this check indicates only that the compiler did not
issue a diagnostic message when given the flag.  Whether the flag has any
effect or even a specific one is beyond the scope of this module.

.. note::
  Since the :command:`try_compile` command forwards flags from variables
  like :variable:`CMAKE_CXX_FLAGS <CMAKE_<LANG>_FLAGS>`, unknown flags
  in such variables may cause a false negative for this check.
#]=======================================================================]

include_guard(GLOBAL)
include(Internal/CheckCompilerFlag)

macro (CHECK_CXX_COMPILER_FLAG _FLAG _RESULT)
  cmake_check_compiler_flag(CXX "${_FLAG}" ${_RESULT})
endmacro ()

# FIXME(#24994): The following module is included only for compatibility
# with projects that accidentally relied on it with CMake 3.26 and below.
include(CheckCXXSourceCompiles)


code:
# Distributed under the OSI-approved BSD 3-Clause License.  See accompanying
# file Copyright.txt or https://cmake.org/licensing for details.

#[=======================================================================[.rst:
CheckCXXSourceCompiles
----------------------

Check if given C++ source compiles and links into an executable.

.. command:: check_cxx_source_compiles

  .. code-block:: cmake

    check_cxx_source_compiles(<code> <resultVar>
                              [FAIL_REGEX <regex1> [<regex2>...]])

  Check that the source supplied in ``<code>`` can be compiled as a C++ source
  file and linked as an executable (so it must contain at least a ``main()``
  function). The result will be stored in the internal cache variable specified
  by ``<resultVar>``, with a boolean true value for success and boolean false
  for failure. If ``FAIL_REGEX`` is provided, then failure is determined by
  checking if anything in the output matches any of the specified regular
  expressions.

  The check is only performed once, with the result cached in the variable named
  by ``<resultVar>``. Every subsequent CMake run will reuse this cached value
  rather than performing the check again, even if the ``<code>`` changes. In
  order to force the check to be re-evaluated, the variable named by
  ``<resultVar>`` must be manually removed from the cache.

  The compile and link commands can be influenced by setting any of the
  following variables prior to calling ``check_cxx_source_compiles()``:

.. include:: /module/CMAKE_REQUIRED_FLAGS.txt

.. include:: /module/CMAKE_REQUIRED_DEFINITIONS.txt

.. include:: /module/CMAKE_REQUIRED_INCLUDES.txt

.. include:: /module/CMAKE_REQUIRED_LINK_OPTIONS.txt

.. include:: /module/CMAKE_REQUIRED_LIBRARIES.txt

.. include:: /module/CMAKE_REQUIRED_QUIET.txt

#]=======================================================================]

include_guard(GLOBAL)
include(Internal/CheckSourceCompiles)

macro(CHECK_CXX_SOURCE_COMPILES SOURCE VAR)
  cmake_check_source_compiles(CXX "${SOURCE}" ${VAR} ${ARGN})
endmacro()