code:
CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE
--------------------------------------------

When saving a failing test's output, this is the maximum size, in bytes, that
will be collected by the :command:`ctest_test` command. Defaults to 307200
(300 KiB). See :variable:`CTEST_CUSTOM_TEST_OUTPUT_TRUNCATION` for possible
truncation modes.

If a test's output contains the literal string "CTEST_FULL_OUTPUT",
the output will not be truncated and may exceed the maximum size.

.. include:: CTEST_CUSTOM_XXX.txt

For controlling the output collection of passing tests, see
:variable:`CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE`.


code:
CTEST_CUSTOM_MAXIMUM_NUMBER_OF_ERRORS
-------------------------------------

The maximum number of errors in a single build step which will be detected.
After this, the :command:`ctest_test` command will truncate the output.
Defaults to 50.

.. include:: CTEST_CUSTOM_XXX.txt

repo_name: lazytadpole/codenamesilverfish

license: mit


code:
CTEST_CUSTOM_MAXIMUM_NUMBER_OF_WARNINGS
---------------------------------------

The maximum number of warnings in a single build step which will be detected.
After this, the :command:`ctest_test` command will truncate the output.
Defaults to 50.

.. include:: CTEST_CUSTOM_XXX.txt


code:
CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE
--------------------------------------------

When saving a passing test's output, this is the maximum size, in bytes, that
will be collected by the :command:`ctest_test` command. Defaults to 1024
(1 KiB). See :variable:`CTEST_CUSTOM_TEST_OUTPUT_TRUNCATION` for possible
truncation modes.

If a test's output contains the literal string "CTEST_FULL_OUTPUT",
the output will not be truncated and may exceed the maximum size.

.. include:: CTEST_CUSTOM_XXX.txt

For controlling the output collection of failing tests, see
:variable:`CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE`.


code:
CTEST_CUSTOM_MEMCHECK_IGNORE
----------------------------

A list of regular expressions to use to exclude tests during the
:command:`ctest_memcheck` command.

.. include:: CTEST_CUSTOM_XXX.txt


code:
CTEST_CUSTOM_POST_MEMCHECK
--------------------------

A list of commands to run at the end of the :command:`ctest_memcheck` command.

.. include:: CTEST_CUSTOM_XXX.txt


code:
CTEST_CUSTOM_POST_TEST
----------------------

A list of commands to run at the end of the :command:`ctest_test` command.

.. include:: CTEST_CUSTOM_XXX.txt


code:
CTEST_CUSTOM_PRE_MEMCHECK
-------------------------

A list of commands to run at the start of the :command:`ctest_memcheck`
command.

.. include:: CTEST_CUSTOM_XXX.txt


code:
CTEST_CUSTOM_PRE_TEST
----------------------

A list of commands to run at the start of the :command:`ctest_test` command.

.. include:: CTEST_CUSTOM_XXX.txt


code:
CTEST_CUSTOM_TESTS_IGNORE
-------------------------

A list of test names to be excluded from the set of tests run by the
:command:`ctest_test` command.

.. include:: CTEST_CUSTOM_XXX.txt


code:
CTEST_CUSTOM_TEST_OUTPUT_TRUNCATION
-----------------------------------

.. versionadded:: 3.24

Set the test output truncation mode in case a maximum size is configured
via the :variable:`CTEST_CUSTOM_MAXIMUM_PASSED_TEST_OUTPUT_SIZE` or
:variable:`CTEST_CUSTOM_MAXIMUM_FAILED_TEST_OUTPUT_SIZE` variables.
By default the ``tail`` of the output will be truncated. Other possible
values are ``middle`` and ``head``.

.. include:: CTEST_CUSTOM_XXX.txt


code:
CTEST_CUSTOM_WARNING_EXCEPTION
------------------------------

A list of regular expressions which will be used to exclude when detecting
warning messages in build outputs by the :command:`ctest_build` command.

.. include:: CTEST_CUSTOM_XXX.txt


code:
CTEST_CUSTOM_WARNING_MATCH
--------------------------

A list of regular expressions which will be used to detect warning messages in
build outputs by the :command:`ctest_build` command.

.. include:: CTEST_CUSTOM_XXX.txt


code:
It is initialized by :manual:`ctest(1)`, but may be edited in a ``CTestCustom``
file. See :command:`ctest_read_custom_files` documentation.


code:
CTEST_CVS_CHECKOUT
------------------

.. versionadded:: 3.1

Deprecated.  Use :variable:`CTEST_CHECKOUT_COMMAND` instead.


code:
CTEST_CVS_COMMAND
-----------------

.. versionadded:: 3.1

Specify the CTest ``CVSCommand`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_CVS_UPDATE_OPTIONS
------------------------

.. versionadded:: 3.1

Specify the CTest ``CVSUpdateOptions`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_DROP_LOCATION
-------------------

.. versionadded:: 3.1

Specify the CTest ``DropLocation`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_DROP_METHOD
-----------------

.. versionadded:: 3.1

Specify the CTest ``DropMethod`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_DROP_SITE
---------------

.. versionadded:: 3.1

Specify the CTest ``DropSite`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_DROP_SITE_CDASH
---------------------

.. versionadded:: 3.1

Specify the CTest ``IsCDash`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_DROP_SITE_PASSWORD
------------------------

.. versionadded:: 3.1

Specify the CTest ``DropSitePassword`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_DROP_SITE_USER
--------------------

.. versionadded:: 3.1

Specify the CTest ``DropSiteUser`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_EXTRA_COVERAGE_GLOB
-------------------------

.. versionadded:: 3.4

A list of regular expressions which will be used to find files which should be
covered by the :command:`ctest_coverage` command.

.. include:: CTEST_CUSTOM_XXX.txt


code:
CTEST_GIT_COMMAND
-----------------

.. versionadded:: 3.1

Specify the CTest ``GITCommand`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_GIT_INIT_SUBMODULES
-------------------------

.. versionadded:: 3.6

Specify the CTest ``GITInitSubmodules`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_GIT_UPDATE_CUSTOM
-----------------------

.. versionadded:: 3.1

Specify the CTest ``GITUpdateCustom`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_GIT_UPDATE_OPTIONS
------------------------

.. versionadded:: 3.1

Specify the CTest ``GITUpdateOptions`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_HG_COMMAND
----------------

.. versionadded:: 3.1

Specify the CTest ``HGCommand`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_HG_UPDATE_OPTIONS
-----------------------

.. versionadded:: 3.1

Specify the CTest ``HGUpdateOptions`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_LABELS_FOR_SUBPROJECTS
----------------------------

.. versionadded:: 3.10

Specify the CTest ``LabelsForSubprojects`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_MEMORYCHECK_COMMAND
-------------------------

.. versionadded:: 3.1

Specify the CTest ``MemoryCheckCommand`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_MEMORYCHECK_COMMAND_OPTIONS
---------------------------------

.. versionadded:: 3.1

Specify the CTest ``MemoryCheckCommandOptions`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_MEMORYCHECK_SANITIZER_OPTIONS
-----------------------------------

.. versionadded:: 3.1

Specify the CTest ``MemoryCheckSanitizerOptions`` setting
in a :manual:`ctest(1)` dashboard client script.

CTest prepends correct sanitizer options ``*_OPTIONS``
environment variable to executed command. CTests adds
its own ``log_path`` to sanitizer options, don't provide your
own ``log_path``.


code:
CTEST_MEMORYCHECK_SUPPRESSIONS_FILE
-----------------------------------

.. versionadded:: 3.1

Specify the CTest ``MemoryCheckSuppressionFile`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_MEMORYCHECK_TYPE
----------------------

.. versionadded:: 3.1

Specify the CTest ``MemoryCheckType`` setting
in a :manual:`ctest(1)` dashboard client script.
Valid values are ``Valgrind``, ``Purify``, ``BoundsChecker``, ``DrMemory``,
``CudaSanitizer``, ``ThreadSanitizer``, ``AddressSanitizer``, ``LeakSanitizer``,
``MemorySanitizer`` and ``UndefinedBehaviorSanitizer``.


code:
CTEST_NIGHTLY_START_TIME
------------------------

.. versionadded:: 3.1

Specify the CTest ``NightlyStartTime`` setting in a :manual:`ctest(1)`
dashboard client script.

Note that this variable must always be set for a nightly build in a
dashboard script. It is needed so that nightly builds can be properly grouped
together in CDash.


code:
CTEST_P4_CLIENT
---------------

.. versionadded:: 3.1

Specify the CTest ``P4Client`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_P4_COMMAND
----------------

.. versionadded:: 3.1

Specify the CTest ``P4Command`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_P4_OPTIONS
----------------

.. versionadded:: 3.1

Specify the CTest ``P4Options`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_P4_UPDATE_OPTIONS
-----------------------

.. versionadded:: 3.1

Specify the CTest ``P4UpdateOptions`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_RESOURCE_SPEC_FILE
------------------------

.. versionadded:: 3.18

Specify the CTest ``ResourceSpecFile`` setting in a :manual:`ctest(1)`
dashboard client script.

This can also be used to specify the resource spec file from a CMake build. If
no ``RESOURCE_SPEC_FILE`` is passed to :command:`ctest_test`, and
``CTEST_RESOURCE_SPEC_FILE`` is not specified in the dashboard script, the
value of this variable from the build is used.


code:
CTEST_RUN_CURRENT_SCRIPT
------------------------

.. versionadded:: 3.11

Setting this to 0 prevents :manual:`ctest(1)` from being run again when it
reaches the end of a script run by calling :option:`ctest -S`.


code:
CTEST_SCP_COMMAND
-----------------

.. versionadded:: 3.1

Legacy option.  Not used.


code:
CTEST_SCRIPT_DIRECTORY
----------------------

The directory containing the top-level CTest script.
The concept is similar to :variable:`CMAKE_SOURCE_DIR`.


code:
CTEST_SITE
----------

.. versionadded:: 3.1

Specify the CTest ``Site`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_SOURCE_DIRECTORY
----------------------

.. versionadded:: 3.1

Specify the CTest ``SourceDirectory`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_SUBMIT_INACTIVITY_TIMEOUT
-------------------------------

.. versionadded:: 3.23

Specify the CTest ``SubmitInactivityTimeout`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_SUBMIT_URL
----------------

.. versionadded:: 3.14

Specify the CTest ``SubmitURL`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_SVN_COMMAND
-----------------

.. versionadded:: 3.1

Specify the CTest ``SVNCommand`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_SVN_OPTIONS
-----------------

.. versionadded:: 3.1

Specify the CTest ``SVNOptions`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_SVN_UPDATE_OPTIONS
------------------------

.. versionadded:: 3.1

Specify the CTest ``SVNUpdateOptions`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_TEST_LOAD
---------------

.. versionadded:: 3.4

Specify the ``TestLoad`` setting in the :ref:`CTest Test Step`
of a :manual:`ctest(1)` dashboard client script.  This sets the
default value for the ``TEST_LOAD`` option of the :command:`ctest_test`
command.


code:
CTEST_TEST_TIMEOUT
------------------

.. versionadded:: 3.1

Specify the CTest ``TimeOut`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_TRIGGER_SITE
------------------

.. versionadded:: 3.1

Legacy option.  Not used.


code:
CTEST_UPDATE_COMMAND
--------------------

.. versionadded:: 3.1

Specify the CTest ``UpdateCommand`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_UPDATE_OPTIONS
--------------------

.. versionadded:: 3.1

Specify the CTest ``UpdateOptions`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_UPDATE_VERSION_ONLY
-------------------------

.. versionadded:: 3.1

Specify the CTest :ref:`UpdateVersionOnly <UpdateVersionOnly>` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_UPDATE_VERSION_OVERRIDE
-----------------------------

.. versionadded:: 3.15

Specify the CTest :ref:`UpdateVersionOverride <UpdateVersionOverride>` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CTEST_USE_LAUNCHERS
-------------------

.. versionadded:: 3.1

Specify the CTest ``UseLaunchers`` setting
in a :manual:`ctest(1)` dashboard client script.


code:
CYGWIN
------

``True`` for Cygwin.

Set to ``true`` when using Cygwin.


code:
ENV
---

Operator to read environment variables.

Use the syntax ``$ENV{VAR}`` to read environment variable ``VAR``.

To test whether an environment variable is defined, use the signature
``if(DEFINED ENV{<name>})`` of the :command:`if` command.

.. note::

  Environment variable names containing special characters like parentheses
  may need to be escaped.  (Policy :policy:`CMP0053` must also be enabled.)
  For example, to get the value of the Windows environment variable
  ``ProgramFiles(x86)``, use:

  .. code-block:: cmake

      set(ProgramFiles_x86 "$ENV{ProgramFiles\(x86\)}")

For general information on environment variables, see the
:ref:`Environment Variables <CMake Language Environment Variables>`
section in the :manual:`cmake-language(7)` manual.


code:
EXECUTABLE_OUTPUT_PATH
----------------------

Old executable location variable.

The target property :prop_tgt:`RUNTIME_OUTPUT_DIRECTORY` supersedes this
variable for a target if it is set.  Executable targets are otherwise placed in
this directory.


code:
GHSMULTI
--------

.. versionadded:: 3.3

``1`` when using :generator:`Green Hills MULTI` generator.

Also, Set to ``1`` when the target system is a Green Hills platform
(i.e. When :variable:`CMAKE_SYSTEM_NAME` is ``GHS-MULTI``).


code:
Ignoring search locations can be useful in cross-compiling environments where
some system directories contain incompatible but possibly linkable libraries.
For example, on cross-compiled cluster environments, this allows a user to
ignore directories containing libraries meant for the front-end machine.


code:
By default, |CMAKE_IGNORE_VAR| is empty. It is intended to be set by the
project or the end user.


code:
:ref:`Semicolon-separated list <CMake Language Lists>` of directories
to be ignored by the various ``find...()`` commands.

For :command:`find_program`, :command:`find_library`, :command:`find_file`,
and :command:`find_path`, any file found in one of the listed directories
will be ignored. The listed directories do not apply recursively, so any
subdirectories to be ignored must also be explicitly listed.
|CMAKE_IGNORE_VAR| does not affect the search *prefixes* used by these
four commands. To ignore individual paths under a search prefix
(e.g. ``bin``, ``include``, ``lib``, etc.), each path must be listed in
|CMAKE_IGNORE_VAR| as a full absolute path. |CMAKE_IGNORE_PREFIX_VAR|
provides a more appropriate way to ignore a whole search prefix.

:command:`find_package` is also affected by |CMAKE_IGNORE_VAR|, but only
for *Config mode* searches. Any ``<Name>Config.cmake`` or
``<name>-config.cmake`` file found in one of the specified directories
will be ignored. In addition, any search *prefix* found in |CMAKE_IGNORE_VAR|
will be skipped for backward compatibility reasons, but new code should
prefer to use |CMAKE_IGNORE_PREFIX_VAR| to ignore prefixes instead.


code:
:ref:`Semicolon-separated list <CMake Language Lists>` of search *prefixes*
to be ignored by the :command:`find_program`, :command:`find_library`,
:command:`find_file`, and :command:`find_path` commands.
The prefixes are also ignored by the *Config mode* of the
:command:`find_package` command (*Module mode* is unaffected).
To ignore specific directories instead, see |CMAKE_IGNORE_NONPREFIX_VAR|.


code:
|CMAKE_IGNORE_VAR| is populated by CMake as part of its platform
and toolchain setup. Its purpose is to ignore locations containing
incompatible binaries meant for the host rather than the target platform.
The project or end user should not modify this variable, they should use
|CMAKE_IGNORE_NONSYSTEM_VAR| instead.


code:
IOS
---

.. versionadded:: 3.14

Set to ``1`` when the target system (:variable:`CMAKE_SYSTEM_NAME`) is ``iOS``.


code:
LIBRARY_OUTPUT_PATH
-------------------

Old library location variable.

The target properties :prop_tgt:`ARCHIVE_OUTPUT_DIRECTORY`,
:prop_tgt:`LIBRARY_OUTPUT_DIRECTORY`, and :prop_tgt:`RUNTIME_OUTPUT_DIRECTORY`
supersede this variable for a target if they are set.  Library targets are
otherwise placed in this directory.


code:
Linker types are case-sensitive and may only contain letters, numbers and
underscores. Linker types defined in all uppercase are reserved for CMake's own
built-in types. The pre-defined linker types are:

``DEFAULT``
  This type corresponds to standard linking, essentially equivalent to
  not specifying :prop_tgt:`LINKER_TYPE` target property.

``SYSTEM``
  Use the standard linker delivered by the platform or the standard toolkit
  (for example, ``SYSTEM`` imply Microsoft linker for all ``MSVC`` compatible
  compilers). This type is supported for the following platforms/compilers:

  * Linux, for ``GNU``, ``Clang``, ``LLVMFlang`` and ``NVIDIA`` compilers.
  * All Apple variants for ``AppleClang``, ``Clang`` and ``GNU`` compilers.
  * Windows, for ``MSVC``, ``GNU``, ``Clang`` and ``NVIDIA`` compilers.

``LLD``
  Use the ``LLVM`` linker. This type is supported for the following
  platforms/compilers:

  * Linux, for ``GNU``, ``Clang``, ``LLVMFlang`` and ``NVIDIA`` compilers.
  * All Apple variants for ``Clang`` and ``AppleClang`` compilers.
  * Windows, for ``GNU``, ``Clang`` compilers with ``GNU`` front-end and
    ``CLang``, ``MSVC`` and ``NVIDIA`` compilers with ``MSVC`` front-end.

``BFD``
  Use the ``GNU`` linker.  This type is supported for the following
  platforms/compilers:

  * Linux, for ``GNU``, ``Clang``, ``LLVMFlang`` and ``NVIDIA`` compilers.
  * Windows, for ``GNU``, ``Clang`` compilers with ``GNU`` front-end.

``GOLD``
  Supported on Linux platform for ``GNU``, ``Clang``, ``LLVMFlang`` and
  ``NVIDIA`` compilers.

``MOLD``
  Use the `mold linker <https://github.com/rui314/mold>`_. This type is
  supported on the following platforms:

  * Linux platform for ``GNU``, ``Clang``, ``LLVMFlang`` and ``NVIDIA``
    compilers.
  * All Apple variants for ``Clang`` and ``AppleClang`` compilers as an
    alias to ``SOLD``.

``SOLD``
  Use the `sold linker <https://github.com/bluewhalesystems/sold>`_. This type
  is only supported on Apple platforms for ``Clang`` and ``AppleClang``
  compilers.

``APPLE_CLASSIC``
  Use the Apple linker in the classic behavior (i.e. before ``Xcode 15.0``).
  This type is only supported on Apple platforms for ``GNU``, ``Clang`` and
  ``AppleClang`` compilers.

``MSVC``
  Use the Microsoft linker. This type is only supported on Windows
  platform for ``MSVC`` and ``Clang`` compiler with ``MSVC`` front-end.


code:
``RESCAN``
  Some linkers are single-pass only.  For such linkers, circular references
  between libraries typically result in unresolved symbols.  This feature
  instructs the linker to search the specified static libraries repeatedly
  until no new undefined references are created.

  Normally, a static library is searched only once in the order that it is
  specified on the command line.  If a symbol in that library is needed to
  resolve an undefined symbol referred to by an object in a library that
  appears later on the command line, the linker would not be able to resolve
  that reference.  By grouping the static libraries with the ``RESCAN``
  feature, they will all be searched repeatedly until all possible references
  are resolved.  This will use linker options like ``--start-group`` and
  ``--end-group``, or on SunOS, ``-z rescan-start`` and ``-z rescan-end``.

  Using this feature has a significant performance cost. It is best to use it
  only when there are unavoidable circular references between two or more
  static libraries.

  This feature is available when using toolchains that target Linux, BSD, and
  SunOS.  It can also be used when targeting Windows platforms if the GNU
  toolchain is used.


code:
``DEFAULT``
  This feature corresponds to standard linking, essentially equivalent to
  using no feature at all.  It is typically only used with the
  :prop_tgt:`LINK_LIBRARY_OVERRIDE` and
  :prop_tgt:`LINK_LIBRARY_OVERRIDE_<LIBRARY>` target properties.

``WHOLE_ARCHIVE``
  Force inclusion of all members of a static library.  This feature is only
  supported for the following platforms, with limitations as noted:

  * Linux.
  * All BSD variants.
  * SunOS.
  * All Apple variants.  The library must be specified as a CMake target name,
    a library file name (such as ``libfoo.a``), or a library file path (such as
    ``/path/to/libfoo.a``).  Due to a limitation of the Apple linker, it
    cannot be specified as a plain library name like ``foo``, where ``foo``
    is not a CMake target.
  * Windows.  When using a MSVC or MSVC-like toolchain, the MSVC version must
    be greater than 1900.
  * Cygwin.
  * MSYS.

``FRAMEWORK``
  This option tells the linker to search for the specified framework using
  the ``-framework`` linker option.  It can only be used on Apple platforms,
  and only with a linker that understands the option used (i.e. the linker
  provided with Xcode, or one compatible with it).

  The framework can be specified as a CMake framework target, a bare framework
  name, or a file path.  If a target is given, that target must have the
  :prop_tgt:`FRAMEWORK` target property set to true.  For a file path, if it
  contains a directory part, that directory will be added as a framework
  search path.

  .. code-block:: cmake

    add_library(lib SHARED ...)
    target_link_libraries(lib PRIVATE "$<LINK_LIBRARY:FRAMEWORK,/path/to/my_framework>")

    # The constructed linker command line will contain:
    #   -F/path/to -framework my_framework

  File paths must conform to one of the following patterns (``*`` is a
  wildcard, and optional parts are shown as ``[...]``):

     * ``[/path/to/]FwName[.framework]``
     * ``[/path/to/]FwName.framework/FwName[suffix]``
     * ``[/path/to/]FwName.framework/Versions/*/FwName[suffix]``

  Note that CMake recognizes and automatically handles framework targets,
  even without using the :genex:`$<LINK_LIBRARY:FRAMEWORK,...>` expression.
  The generator expression can still be used with a CMake target if the
  project wants to be explicit about it, but it is not required to do so.
  The linker command line may have some differences between using the
  generator expression or not, but the final result should be the same.
  On the other hand, if a file path is given, CMake will recognize some paths
  automatically, but not all cases.  The project may want to use
  :genex:`$<LINK_LIBRARY:FRAMEWORK,...>` for file paths so that the expected
  behavior is clear.

  .. versionadded:: 3.25
    The :prop_tgt:`FRAMEWORK_MULTI_CONFIG_POSTFIX_<CONFIG>` target property as
    well as the ``suffix`` of the framework library name are now supported by
    the ``FRAMEWORK`` features.

``NEEDED_FRAMEWORK``
  This is similar to the ``FRAMEWORK`` feature, except it forces the linker
  to link with the framework even if no symbols are used from it.  It uses
  the ``-needed_framework`` option and has the same linker constraints as
  ``FRAMEWORK``.

``REEXPORT_FRAMEWORK``
  This is similar to the ``FRAMEWORK`` feature, except it tells the linker
  that the framework should be available to clients linking to the library
  being created.  It uses the ``-reexport_framework`` option and has the
  same linker constraints as ``FRAMEWORK``.

``WEAK_FRAMEWORK``
  This is similar to the ``FRAMEWORK`` feature, except it forces the linker
  to mark the framework and all references to it as weak imports.  It uses
  the ``-weak_framework`` option and has the same linker constraints as
  ``FRAMEWORK``.

``NEEDED_LIBRARY``
  This is similar to the ``NEEDED_FRAMEWORK`` feature, except it is for use
  with non-framework targets or libraries (Apple platforms only).
  It uses the ``-needed_library`` or ``-needed-l`` option as appropriate,
  and has the same linker constraints as ``NEEDED_FRAMEWORK``.

``REEXPORT_LIBRARY``
  This is similar to the ``REEXPORT_FRAMEWORK`` feature,  except it is for use
  with non-framework targets or libraries (Apple platforms only).
  It uses the ``-reexport_library`` or ``-reexport-l`` option as appropriate,
  and has the same linker constraints as ``REEXPORT_FRAMEWORK``.

``WEAK_LIBRARY``
  This is similar to the ``WEAK_FRAMEWORK`` feature, except it is for use
  with non-framework targets or libraries (Apple platforms only).
  It uses the ``-weak_library`` or ``-weak-l`` option as appropriate,
  and has the same linker constraints as ``WEAK_FRAMEWORK``.


code:
LINUX
-----

.. versionadded:: 3.25

Set to true when the target system is Linux.


code:
MINGW
-----

.. versionadded:: 3.2

Set to a true value when at least one language is enabled
with a compiler targeting the GNU ABI on Windows (MinGW).

Otherwise, this variable is not set by CMake.


code:
MSVC
----

Set to ``true`` when the compiler is some version of Microsoft Visual C++
or another compiler simulating the Visual C++ ``cl`` command-line syntax.

See also the :variable:`MSVC_VERSION` variable.


code:
MSVC10
------

Discouraged.  Use the :variable:`MSVC_VERSION` variable instead.

``True`` when using the Microsoft Visual Studio ``v100`` toolset
(``cl`` version 16) or another compiler that simulates it.


code:
MSVC11
------

Discouraged.  Use the :variable:`MSVC_VERSION` variable instead.

``True`` when using the Microsoft Visual Studio ``v110`` toolset
(``cl`` version 17) or another compiler that simulates it.


code:
MSVC12
------

Discouraged.  Use the :variable:`MSVC_VERSION` variable instead.

``True`` when using the Microsoft Visual Studio ``v120`` toolset
(``cl`` version 18) or another compiler that simulates it.


code:
MSVC14
------

.. versionadded:: 3.1

Discouraged.  Use the :variable:`MSVC_VERSION` variable instead.

``True`` when using the Microsoft Visual Studio ``v140`` or ``v141``
toolset (``cl`` version 19) or another compiler that simulates it.


code:
MSVC60
------

Discouraged.  Use the :variable:`MSVC_VERSION` variable instead.

``True`` when using Microsoft Visual C++ 6.0.

Set to ``true`` when the compiler is version 6.0 of Microsoft Visual C++.


code:
MSVC70
------

Discouraged.  Use the :variable:`MSVC_VERSION` variable instead.

``True`` when using Microsoft Visual C++ 7.0.

Set to ``true`` when the compiler is version 7.0 of Microsoft Visual C++.


code:
MSVC71
------

Discouraged.  Use the :variable:`MSVC_VERSION` variable instead.

``True`` when using Microsoft Visual C++ 7.1.

Set to ``true`` when the compiler is version 7.1 of Microsoft Visual C++.


code:
MSVC80
------

Discouraged.  Use the :variable:`MSVC_VERSION` variable instead.

``True`` when using the Microsoft Visual Studio ``v80`` toolset
(``cl`` version 14) or another compiler that simulates it.


code:
MSVC90
------

Discouraged.  Use the :variable:`MSVC_VERSION` variable instead.

``True`` when using the Microsoft Visual Studio ``v90`` toolset
(``cl`` version 15) or another compiler that simulates it.


code:
MSVC_IDE
--------

``True`` when using the Microsoft Visual C++ IDE.

Set to ``true`` when the target platform is the Microsoft Visual C++ IDE, as
opposed to the command line compiler.

.. note::

  This variable is only available after compiler detection has been performed,
  so it is not available to toolchain files or before the first
  :command:`project` or :command:`enable_language` call which uses an
  MSVC-like compiler.


code:
MSVC_TOOLSET_VERSION
--------------------

.. versionadded:: 3.12

The toolset version of Microsoft Visual C/C++ being used if any.
If MSVC-like is being used, this variable is set based on the version
of the compiler as given by the :variable:`MSVC_VERSION` variable.

Known toolset version numbers are::

  80        = VS 2005 (8.0)
  90        = VS 2008 (9.0)
  100       = VS 2010 (10.0)
  110       = VS 2012 (11.0)
  120       = VS 2013 (12.0)
  140       = VS 2015 (14.0)
  141       = VS 2017 (15.0)
  142       = VS 2019 (16.0)
  143       = VS 2022 (17.0)

Compiler versions newer than those known to CMake will be reported
as the latest known toolset version.

See also the :variable:`MSVC_VERSION` variable.


code:
MSVC_VERSION
------------

The version of Microsoft Visual C/C++ being used if any.
If a compiler simulating Visual C++ is being used, this variable is set
to the toolset version simulated as given by the ``_MSC_VER``
preprocessor definition.

Known version numbers are::

  1200      = VS  6.0
  1300      = VS  7.0
  1310      = VS  7.1
  1400      = VS  8.0 (v80 toolset)
  1500      = VS  9.0 (v90 toolset)
  1600      = VS 10.0 (v100 toolset)
  1700      = VS 11.0 (v110 toolset)
  1800      = VS 12.0 (v120 toolset)
  1900      = VS 14.0 (v140 toolset)
  1910-1919 = VS 15.0 (v141 toolset)
  1920-1929 = VS 16.0 (v142 toolset)
  1930-1939 = VS 17.0 (v143 toolset)

See also the  :variable:`CMAKE_<LANG>_COMPILER_VERSION` and
:variable:`MSVC_TOOLSET_VERSION` variable.


code:
MSYS
----

.. versionadded:: 3.14

``True`` when using the :generator:`MSYS Makefiles` generator.


code:
<PROJECT-NAME>_BINARY_DIR
-------------------------

Top level binary directory for the named project.

A variable is created with the name used in the :command:`project` command,
and is the binary directory for the project.  This can be useful when
:command:`add_subdirectory` is used to connect several projects.


code:
<PROJECT-NAME>_DESCRIPTION
--------------------------

.. versionadded:: 3.12

Value given to the ``DESCRIPTION`` option of the most recent call to the
:command:`project` command with project name ``<PROJECT-NAME>``, if any.


code:
<PROJECT-NAME>_HOMEPAGE_URL
---------------------------

.. versionadded:: 3.12

Value given to the ``HOMEPAGE_URL`` option of the most recent call to the
:command:`project` command with project name ``<PROJECT-NAME>``, if any.


code:
<PROJECT-NAME>_IS_TOP_LEVEL
---------------------------

.. versionadded:: 3.21

A boolean variable indicating whether the named project was called in a top
level ``CMakeLists.txt`` file.

To obtain the value from the most recent call to :command:`project` in
the current directory scope or above, see the
:variable:`PROJECT_IS_TOP_LEVEL` variable.

The variable value will be true in:

* the top-level directory of the project
* the top-level directory of an external project added by
  :module:`ExternalProject`
* a directory added by :command:`add_subdirectory` that does not also contain
  a :command:`project` call
* a directory added by :command:`FetchContent_MakeAvailable`,
  if the fetched content does not contain a :command:`project` call

The variable value will be false in:

* a directory added by :command:`add_subdirectory` that also contains
  a :command:`project` call
* a directory added by :command:`FetchContent_MakeAvailable`,
  if the fetched content contains a :command:`project` call


code:
<PROJECT-NAME>_SOURCE_DIR
-------------------------

Top level source directory for the named project.

A variable is created with the name used in the :command:`project` command,
and is the source directory for the project.  This can be useful when
:command:`add_subdirectory` is used to connect several projects.


code:
<PROJECT-NAME>_VERSION
----------------------

Value given to the ``VERSION`` option of the most recent call to the
:command:`project` command with project name ``<PROJECT-NAME>``, if any.

See also the component-wise version variables
:variable:`<PROJECT-NAME>_VERSION_MAJOR`,
:variable:`<PROJECT-NAME>_VERSION_MINOR`,
:variable:`<PROJECT-NAME>_VERSION_PATCH`, and
:variable:`<PROJECT-NAME>_VERSION_TWEAK`.


code:
<PROJECT-NAME>_VERSION_MAJOR
----------------------------

First version number component of the :variable:`<PROJECT-NAME>_VERSION`
variable as set by the :command:`project` command.


code:
<PROJECT-NAME>_VERSION_MINOR
----------------------------

Second version number component of the :variable:`<PROJECT-NAME>_VERSION`
variable as set by the :command:`project` command.


code:
<PROJECT-NAME>_VERSION_PATCH
----------------------------

Third version number component of the :variable:`<PROJECT-NAME>_VERSION`
variable as set by the :command:`project` command.


code:
<PROJECT-NAME>_VERSION_TWEAK
----------------------------

Fourth version number component of the :variable:`<PROJECT-NAME>_VERSION`
variable as set by the :command:`project` command.


code:
PROJECT_BINARY_DIR
------------------

Full path to build directory for project.

This is the binary directory of the most recent :command:`project` command.


code:
PROJECT_DESCRIPTION
-------------------

.. versionadded:: 3.9

Short project description given to the project command.

This is the description given to the most recently called :command:`project`
command in the current directory scope or above.  To obtain the description
of the top level project, see the :variable:`CMAKE_PROJECT_DESCRIPTION`
variable.


code:
PROJECT_HOMEPAGE_URL
--------------------

.. versionadded:: 3.12

The homepage URL of the project.

This is the homepage URL given to the most recently called :command:`project`
command in the current directory scope or above.  To obtain the homepage URL
of the top level project, see the :variable:`CMAKE_PROJECT_HOMEPAGE_URL`
variable.


code:
PROJECT_IS_TOP_LEVEL
--------------------

.. versionadded:: 3.21

A boolean variable indicating whether the most recently called
:command:`project` command in the current scope or above was in the top
level ``CMakeLists.txt`` file.

Some modules should only be included as part of the top level
``CMakeLists.txt`` file to not cause unintended side effects in the build
tree, and this variable can be used to conditionally execute such code. For
example, consider the :module:`CTest` module, which creates targets and
options:

.. code-block:: cmake

  project(MyProject)
  ...
  if(PROJECT_IS_TOP_LEVEL)
    include(CTest)
  endif()

The variable value will be true in:

* the top-level directory of the project
* the top-level directory of an external project added by
  :module:`ExternalProject`
* a directory added by :command:`add_subdirectory` that does not also contain
  a :command:`project` call
* a directory added by :command:`FetchContent_MakeAvailable`,
  if the fetched content does not contain a :command:`project` call

The variable value will be false in:

* a directory added by :command:`add_subdirectory` that also contains
  a :command:`project` call
* a directory added by :command:`FetchContent_MakeAvailable`,
  if the fetched content contains a :command:`project` call


code:
PROJECT_NAME
------------

Name of the project given to the project command.

This is the name given to the most recently called :command:`project`
command in the current directory scope or above.  To obtain the name of
the top level project, see the :variable:`CMAKE_PROJECT_NAME` variable.


code:
PROJECT_SOURCE_DIR
------------------

This is the source directory of the last call to the
:command:`project` command made in the current directory scope or one
of its parents. Note, it is not affected by calls to
:command:`project` made within a child directory scope (i.e. from
within a call to :command:`add_subdirectory` from the current scope).


code:
PROJECT_VERSION
---------------

Value given to the ``VERSION`` option of the most recent call to the
:command:`project` command, if any.

See also the component-wise version variables
:variable:`PROJECT_VERSION_MAJOR`,
:variable:`PROJECT_VERSION_MINOR`,
:variable:`PROJECT_VERSION_PATCH`, and
:variable:`PROJECT_VERSION_TWEAK`.


code:
PROJECT_VERSION_MAJOR
---------------------

First version number component of the :variable:`PROJECT_VERSION`
variable as set by the :command:`project` command.


code:
PROJECT_VERSION_MINOR
---------------------

Second version number component of the :variable:`PROJECT_VERSION`
variable as set by the :command:`project` command.


code:
PROJECT_VERSION_PATCH
---------------------

Third version number component of the :variable:`PROJECT_VERSION`
variable as set by the :command:`project` command.


code:
PROJECT_VERSION_TWEAK
---------------------

Fourth version number component of the :variable:`PROJECT_VERSION`
variable as set by the :command:`project` command.


code:
<PackageName>_ROOT
------------------

.. versionadded:: 3.12

Calls to :command:`find_package(<PackageName>)` will search in prefixes
specified by the ``<PackageName>_ROOT`` CMake variable, where
``<PackageName>`` is the (case-preserved) name given to the
:command:`find_package` call and ``_ROOT`` is literal.
For example, ``find_package(Foo)`` will search prefixes specified in the
``Foo_ROOT`` CMake variable (if set).  See policy :policy:`CMP0074`.

This variable may hold a single prefix or a
:ref:`semicolon-separated list <CMake Language Lists>` of multiple prefixes.

See also the :envvar:`<PackageName>_ROOT` environment variable.

.. variable:: <PACKAGENAME>_ROOT

  .. versionadded:: 3.27

  Calls to :command:`find_package(<PackageName>)` will also search in
  prefixes specified by the upper-case ``<PACKAGENAME>_ROOT`` CMake
  variable.  See policy :policy:`CMP0144`.


code:
UNIX
----

Set to ``True`` when the target system is UNIX or UNIX-like
(e.g. :variable:`APPLE` and :variable:`CYGWIN`).  The
:variable:`CMAKE_SYSTEM_NAME` variable should be queried if
a more specific understanding of the target system is required.


code:
WIN32
-----

Set to ``True`` when the target system is Windows, including Win64.


code:
WINCE
-----

.. versionadded:: 3.1

True when the :variable:`CMAKE_SYSTEM_NAME` variable is set
to ``WindowsCE``.


code:
WINDOWS_PHONE
-------------

.. versionadded:: 3.1

True when the :variable:`CMAKE_SYSTEM_NAME` variable is set
to ``WindowsPhone``.


code:
WINDOWS_STORE
-------------

.. versionadded:: 3.1

True when the :variable:`CMAKE_SYSTEM_NAME` variable is set
to ``WindowsStore``.


code:
XCODE
-----

.. versionadded:: 3.7

``True`` when using :generator:`Xcode` generator.


code:
XCODE_VERSION
-------------

Version of Xcode (:generator:`Xcode` generator only).

Under the :generator:`Xcode` generator, this is the version of Xcode
as specified in ``Xcode.app/Contents/version.plist`` (such as ``3.1.2``).


code:
                   GNU LESSER GENERAL PUBLIC LICENSE
                       Version 3, 29 June 2007

 Copyright (C) 2007 Free Software Foundation, Inc. <http://fsf.org/>
 Everyone is permitted to copy and distribute verbatim copies
 of this license document, but changing it is not allowed.

  This version of the GNU Lesser General Public License incorporates
the terms and conditions of version 3 of the GNU General Public
License, supplemented by the additional permissions listed below.

  0. Additional Definitions.

  As used herein, "this License" refers to version 3 of the GNU Lesser
General Public License, and the "GNU GPL" refers to version 3 of the GNU
General Public License.

  "The Library" refers to a covered work governed by this License,
other than an Application or a Combined Work as defined below.

  An "Application" is any work that makes use of an interface provided
by the Library, but which is not otherwise based on the Library.
Defining a subclass of a class defined by the Library is deemed a mode
of using an interface provided by the Library.

  A "Combined Work" is a work produced by combining or linking an
Application with the Library.  The particular version of the Library
with which the Combined Work was made is also called the "Linked
Version".

  The "Minimal Corresponding Source" for a Combined Work means the
Corresponding Source for the Combined Work, excluding any source code
for portions of the Combined Work that, considered in isolation, are
based on the Application, and not on the Linked Version.

  The "Corresponding Application Code" for a Combined Work means the
object code and/or source code for the Application, including any data
and utility programs needed for reproducing the Combined Work from the
Application, but excluding the System Libraries of the Combined Work.

  1. Exception to Section 3 of the GNU GPL.

  You may convey a covered work under sections 3 and 4 of this License
without being bound by section 3 of the GNU GPL.

  2. Conveying Modified Versions.

  If you modify a copy of the Library, and, in your modifications, a
facility refers to a function or data to be supplied by an Application
that uses the facility (other than as an argument passed when the
facility is invoked), then you may convey a copy of the modified
version:

   a) under this License, provided that you make a good faith effort to
   ensure that, in the event an Application does not supply the
   function or data, the facility still operates, and performs
   whatever part of its purpose remains meaningful, or

   b) under the GNU GPL, with none of the additional permissions of
   this License applicable to that copy.

  3. Object Code Incorporating Material from Library Header Files.

  The object code form of an Application may incorporate material from
a header file that is part of the Library.  You may convey such object
code under terms of your choice, provided that, if the incorporated
material is not limited to numerical parameters, data structure
layouts and accessors, or small macros, inline functions and templates
(ten or fewer lines in length), you do both of the following:

   a) Give prominent notice with each copy of the object code that the
   Library is used in it and that the Library and its use are
   covered by this License.

   b) Accompany the object code with a copy of the GNU GPL and this license
   document.

  4. Combined Works.

  You may convey a Combined Work under terms of your choice that,
taken together, effectively do not restrict modification of the
portions of the Library contained in the Combined Work and reverse
engineering for debugging such modifications, if you also do each of
the following:

   a) Give prominent notice with each copy of the Combined Work that
   the Library is used in it and that the Library and its use are
   covered by this License.

   b) Accompany the Combined Work with a copy of the GNU GPL and this license
   document.

   c) For a Combined Work that displays copyright notices during
   execution, include the copyright notice for the Library among
   these notices, as well as a reference directing the user to the
   copies of the GNU GPL and this license document.

   d) Do one of the following:

       0) Convey the Minimal Corresponding Source under the terms of this
       License, and the Corresponding Application Code in a form
       suitable for, and under terms that permit, the user to
       recombine or relink the Application with a modified version of
       the Linked Version to produce a modified Combined Work, in the
       manner specified by section 6 of the GNU GPL for conveying
       Corresponding Source.

       1) Use a suitable shared library mechanism for linking with the
       Library.  A suitable mechanism is one that (a) uses at run time
       a copy of the Library already present on the user's computer
       system, and (b) will operate properly with a modified version
       of the Library that is interface-compatible with the Linked
       Version.

   e) Provide Installation Information, but only if you would otherwise
   be required to provide such information under section 6 of the
   GNU GPL, and only to the extent that such information is
   necessary to install and execute a modified version of the
   Combined Work produced by recombining or relinking the
   Application with a modified version of the Linked Version. (If
   you use option 4d0, the Installation Information must accompany
   the Minimal Corresponding Source and Corresponding Application
   Code. If you use option 4d1, you must provide the Installation
   Information in the manner specified by section 6 of the GNU GPL
   for conveying Corresponding Source.)

  5. Combined Libraries.

  You may place library facilities that are a work based on the
Library side by side in a single library together with other library
facilities that are not Applications and are not covered by this
License, and convey such a combined library under terms of your
choice, if you do both of the following:

   a) Accompany the combined library with a copy of the same work based
   on the Library, uncombined with any other library facilities,
   conveyed under the terms of this License.

   b) Give prominent notice with the combined library that part of it
   is a work based on the Library, and explaining where to find the
   accompanying uncombined form of the same work.

  6. Revised Versions of the GNU Lesser General Public License.

  The Free Software Foundation may publish revised and/or new versions
of the GNU Lesser General Public License from time to time. Such new
versions will be similar in spirit to the present version, but may
differ in detail to address new problems or concerns.

  Each version is given a distinguishing version number. If the
Library as you received it specifies that a certain numbered version
of the GNU Lesser General Public License "or any later version"
applies to it, you have the option of following the terms and
conditions either of that published version or of any later version
published by the Free Software Foundation. If the Library as you
received it does not specify a version number of the GNU Lesser
General Public License, you may choose any version of the GNU Lesser
General Public License ever published by the Free Software Foundation.

  If the Library as you received it specifies that a proxy can decide
whether future versions of the GNU Lesser General Public License shall
apply, that proxy's public statement of acceptance of any version is
permanent authorization for you to choose that version for the
Library.


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

#[=======================================================================[.rst:
AddFileDependencies
-------------------

.. deprecated:: 3.20

Add dependencies to a source file.

.. code-block:: cmake

  add_file_dependencies(<source> <files>...)

Adds the given ``<files>`` to the dependencies of file ``<source>``.

Do not use this command in new code.  It is just a wrapper around:

.. code-block:: cmake

  set_property(SOURCE <source> APPEND PROPERTY OBJECT_DEPENDS <files>...)

Instead use the :command:`set_property` command to append to the
:prop_sf:`OBJECT_DEPENDS` source file property directly.

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

function(add_file_dependencies _file)

  set_property(SOURCE "${_file}" APPEND PROPERTY OBJECT_DEPENDS "${ARGN}")

endfunction()


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

#[======================================================================[.rst:
AndroidTestUtilities
------------------------

.. versionadded:: 3.7

Create a test that automatically loads specified data onto an Android device.

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

Use this module to push data needed for testing an Android device behavior
onto a connected Android device. The module will accept files and libraries as
well as separate destinations for each. It will create a test that loads the
files into a device object store and link to them from the specified
destination. The files are only uploaded if they are not already in the object
store.

For example:

.. code-block:: cmake

  include(AndroidTestUtilities)
  android_add_test_data(
    example_setup_test
    FILES <files>...
    LIBS <libs>...
    DEVICE_TEST_DIR "/data/local/tests/example"
    DEVICE_OBJECT_STORE "/sdcard/.ExternalData/SHA"
    )

At build time a test named "example_setup_test" will be created.  Run this test
on the command line with :manual:`ctest(1)` to load the data onto the Android
device.

Module Functions
^^^^^^^^^^^^^^^^

.. command:: android_add_test_data

  .. code-block:: cmake

    android_add_test_data(<test-name>
      [FILES <files>...] [FILES_DEST <device-dir>]
      [LIBS <libs>...]   [LIBS_DEST <device-dir>]
      [DEVICE_OBJECT_STORE <device-dir>]
      [DEVICE_TEST_DIR <device-dir>]
      [NO_LINK_REGEX <strings>...]
      )

  The ``android_add_test_data`` function is used to copy files and libraries
  needed to run project-specific tests. On the host operating system, this is
  done at build time. For on-device testing, the files are loaded onto the
  device by the manufactured test at run time.

  This function accepts the following named parameters:

  ``FILES <files>...``
    zero or more files needed for testing
  ``LIBS <libs>...``
    zero or more libraries needed for testing
  ``FILES_DEST <device-dir>``
    absolute path where the data files are expected to be
  ``LIBS_DEST <device-dir>``
    absolute path where the libraries are expected to be
  ``DEVICE_OBJECT_STORE <device-dir>``
    absolute path to the location where the data is stored on-device
  ``DEVICE_TEST_DIR <device-dir>``
    absolute path to the root directory of the on-device test location
  ``NO_LINK_REGEX <strings>...``
    list of regex strings matching the names of files that should be
    copied from the object store to the testing directory
#]======================================================================]

include(${CMAKE_CURRENT_LIST_DIR}/ExternalData.cmake)

# The parameters to this function should be set to the list of directories,
# files, and libraries that need to be installed prior to testing.
function(android_add_test_data test_name)
  # As the names suggest, oneValueArgs lists the arguments that specify a
  # single value, while multiValueArgs can contain one or more values.
  set(keywordArgs)
  set(oneValueArgs FILES_DEST LIBS_DEST DEVICE_OBJECT_STORE DEVICE_TEST_DIR)
  set(multiValueArgs FILES LIBS NO_LINK_REGEX)

  # For example, if you called this function with FILES </path/to/file>
  # then this path would be stored in the variable AST_FILES.
  # The AST prefix stands for the name of this function (android_add_test_data).
  cmake_parse_arguments(AST "${keywordArgs}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})
  if(NOT AST_DEVICE_TEST_DIR)
    message(FATAL_ERROR "-- You must specify the location of the on device test directory.")
  endif()
  if(NOT AST_DEVICE_OBJECT_STORE)
    message(FATAL_ERROR "-- You must specify the location of the on device object store.")
  endif()
  if(${AST_DEVICE_TEST_DIR} STREQUAL "/")
    message(FATAL_ERROR "-- The device test directory cannot be '/'")
  endif()

  # Copy all test data files into the binary directory, where tests are run.
  # ExternalData will handle fetching DATA{...} references.
  string(REPLACE "|" ";" hash_algs "${_ExternalData_REGEX_EXT}")
  # Convert ExternalData placeholder file names to DATA{} syntax.
  foreach(alg ${hash_algs})
    string(REGEX REPLACE "([^ ;]+)\\.${alg}" "DATA{\\1}" AST_FILES "${AST_FILES}")
  endforeach()

  set(DATA_TARGET_NAME "${test_name}")
  string(FIND "${AST_FILES}" "DATA{" data_files_found)
  if(${data_files_found} GREATER "-1")
    # Use ExternalData if any DATA{} files were found.
    ExternalData_Expand_Arguments(
      ${DATA_TARGET_NAME}
      extern_data_output
      ${AST_FILES})
    ExternalData_Add_Target(${DATA_TARGET_NAME})
  else()
    add_custom_target(${DATA_TARGET_NAME} ALL)
    set(extern_data_output ${AST_FILES})
  endif()

  # For regular files on Linux, just copy them directly.
  foreach(path ${AST_FILES})
    foreach(output ${extern_data_output})
      if(${output} STREQUAL ${path})
        # Check if a destination was specified.  If not, we copy by default
        # into this project's binary directory, preserving its relative path.
        if(AST_${VAR}_DEST)
          set(DEST ${CMAKE_BINARY_DIR}/${parent_dir}/${AST_${VAR}_DEST})
        else()
          get_filename_component(parent_dir ${path} DIRECTORY)
          set(DEST "${CMAKE_BINARY_DIR}/${parent_dir}")
        endif()
        get_filename_component(extern_data_source ${output} REALPATH)
        get_filename_component(extern_data_basename ${output} NAME)
        add_custom_command(
          TARGET ${DATA_TARGET_NAME} POST_BUILD
          DEPENDS ${extern_data_source}
          COMMAND ${CMAKE_COMMAND} -E copy_if_different ${extern_data_source} ${DEST}/${extern_data_basename}
        )
      endif()
    endforeach()
  endforeach()

  if(ANDROID)
    string(REGEX REPLACE "DATA{([^ ;]+)}" "\\1"  processed_FILES "${AST_FILES}")
    add_test(
      NAME ${test_name}
      COMMAND ${CMAKE_COMMAND}
      "-Darg_files_dest=${AST_FILES_DEST}"
      "-Darg_libs_dest=${AST_LIBS_DEST}"
      "-Darg_dev_test_dir=${AST_DEVICE_TEST_DIR}"
      "-Darg_dev_obj_store=${AST_DEVICE_OBJECT_STORE}"
      "-Darg_no_link_regex=${AST_NO_LINK_REGEX}"
      "-Darg_files=${processed_FILES}"
      "-Darg_libs=${AST_LIBS}"
      "-Darg_src_dir=${CMAKE_CURRENT_SOURCE_DIR}"
      -P ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/AndroidTestUtilities/PushToAndroidDevice.cmake)
  endif()
endfunction()


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

# This function handles pushing all of the test files needed to the device.
# It places the data files in the object store and makes links to them from
# the appropriate directories.
#
# This function accepts the following named parameters:
# DIRS          : one or more directories needed for testing.
# FILES         : one or more files needed for testing.
# LIBS          : one or more libraries needed for testing.
# DIRS_DEST     : specify where the directories should be installed.
# FILES_DEST    : specify where the files should be installed.
# LIBS_DEST     : specify where the libraries should be installed.
# DEV_OBJ_STORE : specify where the actual data files should be placed.
# DEV_TEST_DIR  : specify the root file for the module test directory.
# The DEV_OBJ_STORE and DEV_TEST_DIR variables are required.

# The parameters to this function should be set to the list of directories,
# files, and libraries that need to be installed prior to testing.
function(android_push_test_files_to_device)

  # The functions in the module need the adb executable.
  find_program(adb_executable adb)
  if(NOT adb_executable)
    message(FATAL_ERROR "could not find adb")
  endif()

  function(execute_adb_command)
    execute_process(COMMAND ${adb_executable} ${ARGN} RESULT_VARIABLE res_var OUTPUT_VARIABLE out_var ERROR_VARIABLE err_var)
    set(out_var ${out_var} PARENT_SCOPE)
    if(res_var)
      string(REGEX REPLACE ";" " " com "${ARGN}")
      message(FATAL_ERROR "Error occurred during adb command: adb ${com}\nError: ${err_var}.")
    endif()
  endfunction()

  # Checks to make sure that a given file exists on the device. If it does,
  # if(file_exists) will return true.
  macro(check_device_file_exists device_file file_exists)
    set(${file_exists} "")
    execute_process(
      COMMAND ${adb_executable} shell ls ${device_file}
      OUTPUT_VARIABLE out_var ERROR_VARIABLE out_var)
    if(NOT out_var) # when a directory exists but is empty the output is empty
      set(${file_exists} "YES")
    else()
      string(FIND ${out_var} "No such file or directory" no_file_exists)
      if(${no_file_exists} STREQUAL "-1") # -1 means the file exists
        set(${file_exists} "YES")
      endif()
    endif()
  endmacro()

  # Checks to see if a filename matches a regex.
  function(filename_regex filename reg_ex)
    string(REGEX MATCH ${reg_ex} filename_match ${filename})
    set(filename_match ${filename_match} PARENT_SCOPE)
  endfunction()

  # If a file with given name exists in the CMAKE_BINARY_DIR then use that file.
  # Otherwise use the file with root in CMAKE_CURRENT_SOURCE_DIR.
  macro(set_absolute_path relative_path absolute_path)
    set(${absolute_path} ${arg_src_dir}/${relative_path})
    if(EXISTS ${CMAKE_BINARY_DIR}/${relative_path})
      set(${absolute_path} ${CMAKE_BINARY_DIR}/${relative_path})
    endif()
    if(NOT EXISTS ${${absolute_path}})
      if(EXISTS ${relative_path})
        set(${absolute_path} ${relative_path})
      else()
        message(FATAL_ERROR "Cannot find file for specified path: ${relative_path}")
      endif()
    endif()
  endmacro()

  # This function pushes the data into the device object store and
  # creates a link to that data file in a specified location.
  #
  # This function requires the following un-named parameters:
  # data_path        : absolute path to data to load into dev obj store.
  # dev_object_store : absolute path to the device object store directory.
  # link_origin      : absolute path to the origin of the link to the dev obj store data file.
  function(push_and_link data_path dev_object_store link_origin)
    FILE(SHA1 ${data_path} hash_val)
    set(obj_store_dst ${dev_object_store}/${hash_val})
    check_device_file_exists(${obj_store_dst} obj_store_file_exists)
    # TODO: Verify that the object store file is indeed hashed correctly. Could use md5.
    if(NOT obj_store_file_exists)
      execute_adb_command(push ${data_path} ${obj_store_dst})
    endif()
    check_device_file_exists(${link_origin} link_exists)
    if(link_exists)
      execute_adb_command(shell rm -f ${link_origin})
    endif()
    foreach(ex ${arg_no_link_regex})
      filename_regex(${data_path} ${ex})
      LIST(APPEND match_ex ${filename_match})
    endforeach()
    if(match_ex)
      execute_adb_command(shell cp ${obj_store_dst} ${link_origin})
    else()
      execute_adb_command(shell ln -s ${obj_store_dst} ${link_origin})
    endif()
  endfunction()

  #----------------------------------------------------------------------------
  #--------------------Beginning of actual function----------------------------
  #----------------------------------------------------------------------------
  set(oneValueArgs FILES_DEST LIBS_DEST DEV_TEST_DIR DEV_OBJ_STORE)
  set(multiValueArgs FILES LIBS)
  cmake_parse_arguments(_ptd "" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

  # Setup of object store and test dir.
  check_device_file_exists(${_ptd_DEV_OBJ_STORE} dev_obj_store_exists)
  if(NOT dev_obj_store_exists)
    execute_adb_command(shell mkdir -p ${_ptd_DEV_OBJ_STORE})
  endif()
  check_device_file_exists(${_ptd_DEV_TEST_DIR} test_dir_exists)
  if(test_dir_exists)
    # This is protected in the SetupProjectTests module.
    execute_adb_command(shell rm -r ${_ptd_DEV_TEST_DIR})
  endif()
  execute_adb_command(shell mkdir -p ${_ptd_DEV_TEST_DIR})

  # Looping over the various types of test data possible.
  foreach(TYPE ${multiValueArgs})
    if(_ptd_${TYPE})

      # determine if the data type destination has been explicitly specified.
      if(_ptd_${TYPE}_DEST)
        set(dest ${_ptd_${TYPE}_DEST})
      else()
        if(${TYPE} STREQUAL LIBS)
          set(dest ${_ptd_DEV_TEST_DIR}/lib)
        else()
          set(dest ${_ptd_DEV_TEST_DIR})
        endif()
      endif()
      execute_adb_command(shell mkdir -p ${dest})

      # Loop over the files passed in
      foreach(relative_path ${_ptd_${TYPE}})
        # The absolute path can be through the source directory or the build directory.
        # If the file/dir exists in the build directory that version is chosen.
        set_absolute_path(${relative_path} absolute_path)
        # Need to transfer all data files in the data directories to the device
        # except those explicitly ignored.
        if(${TYPE} STREQUAL FILES)
          get_filename_component(file_dir ${relative_path} DIRECTORY)
          # dest was determined earlier, relative_path is a dir, file is path from relative path to a data
          set(cur_dest ${dest}/${relative_path})
          set(on_dev_dir ${dest}/${file_dir})
          execute_adb_command(shell mkdir -p ${on_dev_dir})
          if(IS_SYMLINK ${absolute_path})
            get_filename_component(real_data_origin ${absolute_path} REALPATH)
            push_and_link(${real_data_origin} ${_ptd_DEV_OBJ_STORE} ${cur_dest})
          else()
            push_and_link(${absolute_path} ${_ptd_DEV_OBJ_STORE} ${cur_dest})
          endif()
        else() # LIBS
          execute_adb_command(push ${absolute_path} ${dest})
        endif()
      endforeach()
    endif()
  endforeach()
endfunction()

android_push_test_files_to_device(
  FILES_DEST ${arg_files_dest}
  LIBS_DEST ${arg_libs_dest}
  DEV_TEST_DIR ${arg_dev_test_dir}
  DEV_OBJ_STORE ${arg_dev_obj_store}
  FILES ${arg_files}
  LIBS ${arg_libs}
  )


code:
# This is a basic version file for the Config-mode of find_package().
# It is used by write_basic_package_version_file() as input file for configure_file()
# to create a version-file which can be installed along a config.cmake file.
#
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
# the requested version string are exactly the same and it sets
# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version.
# The variable CVF_VERSION must be set before calling configure_file().

set(PACKAGE_VERSION "@CVF_VERSION@")

if (PACKAGE_FIND_VERSION_RANGE)
  # Package version must be in the requested version range
  if ((PACKAGE_FIND_VERSION_RANGE_MIN STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MIN)
      OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_GREATER PACKAGE_FIND_VERSION_MAX)
        OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_GREATER_EQUAL PACKAGE_FIND_VERSION_MAX)))
    set(PACKAGE_VERSION_COMPATIBLE FALSE)
  else()
    set(PACKAGE_VERSION_COMPATIBLE TRUE)
  endif()
else()
  if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
    set(PACKAGE_VERSION_COMPATIBLE FALSE)
  else()
    set(PACKAGE_VERSION_COMPATIBLE TRUE)
    if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
      set(PACKAGE_VERSION_EXACT TRUE)
    endif()
  endif()
endif()

@CVF_ARCH_INDEPENDENT_CHECK@


code:
# This is a basic version file for the Config-mode of find_package().
# It is used by write_basic_package_version_file() as input file for configure_file()
# to create a version-file which can be installed along a config.cmake file.
#
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
# the requested version string are exactly the same and it sets
# PACKAGE_VERSION_COMPATIBLE if the current version is equal to the requested version.
# The tweak version component is ignored.
# The variable CVF_VERSION must be set before calling configure_file().

if (PACKAGE_FIND_VERSION_RANGE)
  message(AUTHOR_WARNING
    "`find_package()` specify a version range but the version strategy "
    "(ExactVersion) of the module `${PACKAGE_FIND_NAME}` is incompatible "
    "with this request. Only the lower endpoint of the range will be used.")
endif()

set(PACKAGE_VERSION "@CVF_VERSION@")

if("@CVF_VERSION@" MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)") # strip the tweak version
  set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}")
  set(CVF_VERSION_MINOR "${CMAKE_MATCH_2}")
  set(CVF_VERSION_PATCH "${CMAKE_MATCH_3}")

  if(NOT CVF_VERSION_MAJOR VERSION_EQUAL 0)
    string(REGEX REPLACE "^0+" "" CVF_VERSION_MAJOR "${CVF_VERSION_MAJOR}")
  endif()
  if(NOT CVF_VERSION_MINOR VERSION_EQUAL 0)
    string(REGEX REPLACE "^0+" "" CVF_VERSION_MINOR "${CVF_VERSION_MINOR}")
  endif()
  if(NOT CVF_VERSION_PATCH VERSION_EQUAL 0)
    string(REGEX REPLACE "^0+" "" CVF_VERSION_PATCH "${CVF_VERSION_PATCH}")
  endif()

  set(CVF_VERSION_NO_TWEAK "${CVF_VERSION_MAJOR}.${CVF_VERSION_MINOR}.${CVF_VERSION_PATCH}")
else()
  set(CVF_VERSION_NO_TWEAK "@CVF_VERSION@")
endif()

if(PACKAGE_FIND_VERSION MATCHES "^([0-9]+)\\.([0-9]+)\\.([0-9]+)") # strip the tweak version
  set(REQUESTED_VERSION_MAJOR "${CMAKE_MATCH_1}")
  set(REQUESTED_VERSION_MINOR "${CMAKE_MATCH_2}")
  set(REQUESTED_VERSION_PATCH "${CMAKE_MATCH_3}")

  if(NOT REQUESTED_VERSION_MAJOR VERSION_EQUAL 0)
    string(REGEX REPLACE "^0+" "" REQUESTED_VERSION_MAJOR "${REQUESTED_VERSION_MAJOR}")
  endif()
  if(NOT REQUESTED_VERSION_MINOR VERSION_EQUAL 0)
    string(REGEX REPLACE "^0+" "" REQUESTED_VERSION_MINOR "${REQUESTED_VERSION_MINOR}")
  endif()
  if(NOT REQUESTED_VERSION_PATCH VERSION_EQUAL 0)
    string(REGEX REPLACE "^0+" "" REQUESTED_VERSION_PATCH "${REQUESTED_VERSION_PATCH}")
  endif()

  set(REQUESTED_VERSION_NO_TWEAK
      "${REQUESTED_VERSION_MAJOR}.${REQUESTED_VERSION_MINOR}.${REQUESTED_VERSION_PATCH}")
else()
  set(REQUESTED_VERSION_NO_TWEAK "${PACKAGE_FIND_VERSION}")
endif()

if(REQUESTED_VERSION_NO_TWEAK STREQUAL CVF_VERSION_NO_TWEAK)
  set(PACKAGE_VERSION_COMPATIBLE TRUE)
else()
  set(PACKAGE_VERSION_COMPATIBLE FALSE)
endif()

if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
  set(PACKAGE_VERSION_EXACT TRUE)
endif()

@CVF_ARCH_INDEPENDENT_CHECK@


code:
# This is a basic version file for the Config-mode of find_package().
# It is used by write_basic_package_version_file() as input file for configure_file()
# to create a version-file which can be installed along a config.cmake file.
#
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
# the requested version string are exactly the same and it sets
# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version,
# but only if the requested major version is the same as the current one.
# The variable CVF_VERSION must be set before calling configure_file().

set(PACKAGE_VERSION "@CVF_VERSION@")

if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
  set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()

  if("@CVF_VERSION@" MATCHES "^([0-9]+)\\.")
    set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}")
    if(NOT CVF_VERSION_MAJOR VERSION_EQUAL 0)
      string(REGEX REPLACE "^0+" "" CVF_VERSION_MAJOR "${CVF_VERSION_MAJOR}")
    endif()
  else()
    set(CVF_VERSION_MAJOR "@CVF_VERSION@")
  endif()

  if(PACKAGE_FIND_VERSION_RANGE)
    # both endpoints of the range must have the expected major version
    math (EXPR CVF_VERSION_MAJOR_NEXT "${CVF_VERSION_MAJOR} + 1")
    if (NOT PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR
        OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX_MAJOR STREQUAL CVF_VERSION_MAJOR)
          OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND NOT PACKAGE_FIND_VERSION_MAX VERSION_LESS_EQUAL CVF_VERSION_MAJOR_NEXT)))
      set(PACKAGE_VERSION_COMPATIBLE FALSE)
    elseif(PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR
        AND ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS_EQUAL PACKAGE_FIND_VERSION_MAX)
        OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MAX)))
      set(PACKAGE_VERSION_COMPATIBLE TRUE)
    else()
      set(PACKAGE_VERSION_COMPATIBLE FALSE)
    endif()
  else()
    if(PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR)
      set(PACKAGE_VERSION_COMPATIBLE TRUE)
    else()
      set(PACKAGE_VERSION_COMPATIBLE FALSE)
    endif()

    if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
      set(PACKAGE_VERSION_EXACT TRUE)
    endif()
  endif()
endif()

@CVF_ARCH_INDEPENDENT_CHECK@


code:
# This is a basic version file for the Config-mode of find_package().
# It is used by write_basic_package_version_file() as input file for configure_file()
# to create a version-file which can be installed along a config.cmake file.
#
# The created file sets PACKAGE_VERSION_EXACT if the current version string and
# the requested version string are exactly the same and it sets
# PACKAGE_VERSION_COMPATIBLE if the current version is >= requested version,
# but only if the requested major and minor versions are the same as the current
# one.
# The variable CVF_VERSION must be set before calling configure_file().

set(PACKAGE_VERSION "@CVF_VERSION@")

if(PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION)
  set(PACKAGE_VERSION_COMPATIBLE FALSE)
else()

  if("@CVF_VERSION@" MATCHES "^([0-9]+)\\.([0-9]+)")
    set(CVF_VERSION_MAJOR "${CMAKE_MATCH_1}")
    set(CVF_VERSION_MINOR "${CMAKE_MATCH_2}")

    if(NOT CVF_VERSION_MAJOR VERSION_EQUAL 0)
      string(REGEX REPLACE "^0+" "" CVF_VERSION_MAJOR "${CVF_VERSION_MAJOR}")
    endif()
    if(NOT CVF_VERSION_MINOR VERSION_EQUAL 0)
      string(REGEX REPLACE "^0+" "" CVF_VERSION_MINOR "${CVF_VERSION_MINOR}")
    endif()
  else()
    set(CVF_VERSION_MAJOR "@CVF_VERSION@")
    set(CVF_VERSION_MINOR "")
  endif()

  if(PACKAGE_FIND_VERSION_RANGE)
    # both endpoints of the range must have the expected major and minor versions
    math (EXPR CVF_VERSION_MINOR_NEXT "${CVF_VERSION_MINOR} + 1")
    if (NOT (PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR
          AND PACKAGE_FIND_VERSION_MIN_MINOR STREQUAL CVF_VERSION_MINOR)
        OR ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE"
            AND NOT (PACKAGE_FIND_VERSION_MAX_MAJOR STREQUAL CVF_VERSION_MAJOR
              AND PACKAGE_FIND_VERSION_MAX_MINOR STREQUAL CVF_VERSION_MINOR))
          OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE"
            AND NOT PACKAGE_FIND_VERSION_MAX VERSION_LESS_EQUAL ${CVF_VERSION_MAJOR}.${CVF_VERSION_MINOR_NEXT})))
      set(PACKAGE_VERSION_COMPATIBLE FALSE)
    elseif(PACKAGE_FIND_VERSION_MIN_MAJOR STREQUAL CVF_VERSION_MAJOR
        AND PACKAGE_FIND_VERSION_MIN_MINOR STREQUAL CVF_VERSION_MINOR
        AND ((PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "INCLUDE" AND PACKAGE_VERSION VERSION_LESS_EQUAL PACKAGE_FIND_VERSION_MAX)
        OR (PACKAGE_FIND_VERSION_RANGE_MAX STREQUAL "EXCLUDE" AND PACKAGE_VERSION VERSION_LESS PACKAGE_FIND_VERSION_MAX)))
      set(PACKAGE_VERSION_COMPATIBLE TRUE)
    else()
      set(PACKAGE_VERSION_COMPATIBLE FALSE)
    endif()
  else()
    if(NOT PACKAGE_FIND_VERSION_MAJOR VERSION_EQUAL 0)
      string(REGEX REPLACE "^0+" "" PACKAGE_FIND_VERSION_MAJOR "${PACKAGE_FIND_VERSION_MAJOR}")
    endif()
    if(NOT PACKAGE_FIND_VERSION_MINOR VERSION_EQUAL 0)
      string(REGEX REPLACE "^0+" "" PACKAGE_FIND_VERSION_MINOR "${PACKAGE_FIND_VERSION_MINOR}")
    endif()

    if((PACKAGE_FIND_VERSION_MAJOR STREQUAL CVF_VERSION_MAJOR) AND
        (PACKAGE_FIND_VERSION_MINOR STREQUAL CVF_VERSION_MINOR))
      set(PACKAGE_VERSION_COMPATIBLE TRUE)
    else()
      set(PACKAGE_VERSION_COMPATIBLE FALSE)
    endif()

    if(PACKAGE_FIND_VERSION STREQUAL PACKAGE_VERSION)
      set(PACKAGE_VERSION_EXACT TRUE)
    endif()
  endif()
endif()

@CVF_ARCH_INDEPENDENT_CHECK@