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

#[=======================================================================[.rst:
FetchContent
------------------

.. versionadded:: 3.11

.. only:: html

  .. contents::

.. note:: The :guide:`Using Dependencies Guide` provides a high-level
  introduction to this general topic. It provides a broader overview of
  where the ``FetchContent`` module fits into the bigger picture,
  including its relationship to the :command:`find_package` command.
  The guide is recommended pre-reading before moving on to the details below.

Overview
^^^^^^^^

This module enables populating content at configure time via any method
supported by the :module:`ExternalProject` module.  Whereas
:command:`ExternalProject_Add` downloads at build time, the
``FetchContent`` module makes content available immediately, allowing the
configure step to use the content in commands like :command:`add_subdirectory`,
:command:`include` or :command:`file` operations.

Content population details should be defined separately from the command that
performs the actual population.  This separation ensures that all the
dependency details are defined before anything might try to use them to
populate content.  This is particularly important in more complex project
hierarchies where dependencies may be shared between multiple projects.

The following shows a typical example of declaring content details for some
dependencies and then ensuring they are populated with a separate call:

.. code-block:: cmake

  FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://github.com/google/googletest.git
    GIT_TAG        703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
  )
  FetchContent_Declare(
    myCompanyIcons
    URL      https://intranet.mycompany.com/assets/iconset_1.12.tar.gz
    URL_HASH MD5=5588a7b18261c20068beabfb4f530b87
  )

  FetchContent_MakeAvailable(googletest myCompanyIcons)

The :command:`FetchContent_MakeAvailable` command ensures the named
dependencies have been populated, either by an earlier call or by populating
them itself.  When performing the population, it will also add them to the
main build, if possible, so that the main build can use the populated
projects' targets, etc.  See the command's documentation for how these steps
are performed.

When using a hierarchical project arrangement, projects at higher levels in
the hierarchy are able to override the declared details of content specified
anywhere lower in the project hierarchy.  The first details to be declared
for a given dependency take precedence, regardless of where in the project
hierarchy that occurs.  Similarly, the first call that tries to populate a
dependency "wins", with subsequent populations reusing the result of the
first instead of repeating the population again.
See the :ref:`Examples <fetch-content-examples>` which demonstrate
this scenario.

In some cases, the main project may need to have more precise control over
the population, or it may be required to explicitly define the population
steps in a way that cannot be captured by the declared details alone.
For such situations, the lower level :command:`FetchContent_GetProperties` and
:command:`FetchContent_Populate` commands can be used.  These lack the richer
features provided by :command:`FetchContent_MakeAvailable` though, so their
direct use should be considered a last resort.  The typical pattern of such
custom steps looks like this:

.. code-block:: cmake

  # NOTE: Where possible, prefer to use FetchContent_MakeAvailable()
  #       instead of custom logic like this

  # Check if population has already been performed
  FetchContent_GetProperties(depname)
  if(NOT depname_POPULATED)
    # Fetch the content using previously declared details
    FetchContent_Populate(depname)

    # Set custom variables, policies, etc.
    # ...

    # Bring the populated content into the build
    add_subdirectory(${depname_SOURCE_DIR} ${depname_BINARY_DIR})
  endif()

The ``FetchContent`` module also supports defining and populating
content in a single call, with no check for whether the content has been
populated elsewhere already.  This should not be done in projects, but may
be appropriate for populating content in CMake's script mode.
See :command:`FetchContent_Populate` for details.

Commands
^^^^^^^^

.. command:: FetchContent_Declare

  .. code-block:: cmake

    FetchContent_Declare(
      <name>
      <contentOptions>...
      [SYSTEM]
      [OVERRIDE_FIND_PACKAGE |
       FIND_PACKAGE_ARGS args...]
    )

  The ``FetchContent_Declare()`` function records the options that describe
  how to populate the specified content.  If such details have already
  been recorded earlier in this project (regardless of where in the project
  hierarchy), this and all later calls for the same content ``<name>`` are
  ignored.  This "first to record, wins" approach is what allows hierarchical
  projects to have parent projects override content details of child projects.

  The content ``<name>`` can be any string without spaces, but good practice
  would be to use only letters, numbers and underscores.  The name will be
  treated case-insensitively and it should be obvious for the content it
  represents, often being the name of the child project or the value given
  to its top level :command:`project` command (if it is a CMake project).
  For well-known public projects, the name should generally be the official
  name of the project.  Choosing an unusual name makes it unlikely that other
  projects needing that same content will use the same name, leading to
  the content being populated multiple times.

  The ``<contentOptions>`` can be any of the download, update or patch options
  that the :command:`ExternalProject_Add` command understands.  The configure,
  build, install and test steps are explicitly disabled and therefore options
  related to them will be ignored.  The ``SOURCE_SUBDIR`` option is an
  exception, see :command:`FetchContent_MakeAvailable` for details on how that
  affects behavior.

  In most cases, ``<contentOptions>`` will just be a couple of options defining
  the download method and method-specific details like a commit tag or archive
  hash.  For example:

  .. code-block:: cmake

    FetchContent_Declare(
      googletest
      GIT_REPOSITORY https://github.com/google/googletest.git
      GIT_TAG        703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
    )

    FetchContent_Declare(
      myCompanyIcons
      URL      https://intranet.mycompany.com/assets/iconset_1.12.tar.gz
      URL_HASH MD5=5588a7b18261c20068beabfb4f530b87
    )

    FetchContent_Declare(
      myCompanyCertificates
      SVN_REPOSITORY svn+ssh://svn.mycompany.com/srv/svn/trunk/certs
      SVN_REVISION   -r12345
    )

  Where contents are being fetched from a remote location and you do not
  control that server, it is advisable to use a hash for ``GIT_TAG`` rather
  than a branch or tag name.  A commit hash is more secure and helps to
  confirm that the downloaded contents are what you expected.

  .. versionchanged:: 3.14
    Commands for the download, update or patch steps can access the terminal.
    This may be needed for things like password prompts or real-time display
    of command progress.

  .. versionadded:: 3.22
    The :variable:`CMAKE_TLS_VERIFY`, :variable:`CMAKE_TLS_CAINFO`,
    :variable:`CMAKE_NETRC` and :variable:`CMAKE_NETRC_FILE` variables now
    provide the defaults for their corresponding content options, just like
    they do for :command:`ExternalProject_Add`. Previously, these variables
    were ignored by the ``FetchContent`` module.

  .. versionadded:: 3.24

    ``FIND_PACKAGE_ARGS``
      This option is for scenarios where the
      :command:`FetchContent_MakeAvailable` command may first try a call to
      :command:`find_package` to satisfy the dependency for ``<name>``.
      By default, such a call would be simply ``find_package(<name>)``, but
      ``FIND_PACKAGE_ARGS`` can be used to provide additional arguments to be
      appended after the ``<name>``.  ``FIND_PACKAGE_ARGS`` can also be given
      with nothing after it, which indicates that :command:`find_package` can
      still be called if :variable:`FETCHCONTENT_TRY_FIND_PACKAGE_MODE` is
      set to ``OPT_IN`` or is not set.

      Everything after the ``FIND_PACKAGE_ARGS`` keyword is appended to the
      :command:`find_package` call, so all other ``<contentOptions>`` must
      come before the ``FIND_PACKAGE_ARGS`` keyword.  If the
      :variable:`CMAKE_FIND_PACKAGE_TARGETS_GLOBAL` variable is set to true
      at the time ``FetchContent_Declare()`` is called, a ``GLOBAL`` keyword
      will be appended to the :command:`find_package` arguments if it was
      not already specified.  It will also be appended if
      ``FIND_PACKAGE_ARGS`` was not given, but
      :variable:`FETCHCONTENT_TRY_FIND_PACKAGE_MODE` was set to ``ALWAYS``.

      ``OVERRIDE_FIND_PACKAGE`` cannot be used when ``FIND_PACKAGE_ARGS`` is
      given.

      :ref:`dependency_providers` discusses another way that
      :command:`FetchContent_MakeAvailable` calls can be redirected.
      ``FIND_PACKAGE_ARGS`` is intended for project control, whereas
      dependency providers allow users to override project behavior.

    ``OVERRIDE_FIND_PACKAGE``
      When a ``FetchContent_Declare(<name> ...)`` call includes this option,
      subsequent calls to ``find_package(<name> ...)`` will ensure that
      ``FetchContent_MakeAvailable(<name>)`` has been called, then use the
      config package files in the :variable:`CMAKE_FIND_PACKAGE_REDIRECTS_DIR`
      directory (which are usually created by ``FetchContent_MakeAvailable()``).
      This effectively makes :command:`FetchContent_MakeAvailable` override
      :command:`find_package` for the named dependency, allowing the former to
      satisfy the package requirements of the latter.  ``FIND_PACKAGE_ARGS``
      cannot be used when ``OVERRIDE_FIND_PACKAGE`` is given.

      If a :ref:`dependency provider <dependency_providers>` has been set
      and the project calls :command:`find_package` for the ``<name>``
      dependency, ``OVERRIDE_FIND_PACKAGE`` will not prevent the provider
      from seeing that call.  Dependency providers always have the opportunity
      to intercept any direct call to :command:`find_package`, except if that
      call contains the ``BYPASS_PROVIDER`` option.

  .. versionadded:: 3.25

    ``SYSTEM``
      If the ``SYSTEM`` argument is provided, the :prop_dir:`SYSTEM` directory
      property of a subdirectory added by
      :command:`FetchContent_MakeAvailable` will be set to true.  This will
      affect non-imported targets created as part of that command.
      See the :prop_tgt:`SYSTEM` target property documentation for a more
      detailed discussion of the effects.

.. command:: FetchContent_MakeAvailable

  .. versionadded:: 3.14

  .. code-block:: cmake

    FetchContent_MakeAvailable(<name1> [<name2>...])

  This command ensures that each of the named dependencies are made available
  to the project by the time it returns.  There must have been a call to
  :command:`FetchContent_Declare` for each dependency, and the first such call
  will control how that dependency will be made available, as described below.

  If ``<lowercaseName>_SOURCE_DIR`` is not set:

  * .. versionadded:: 3.24

      If a :ref:`dependency provider <dependency_providers>` is set, call the
      provider's command with ``FETCHCONTENT_MAKEAVAILABLE_SERIAL`` as the
      first argument, followed by the arguments of the first call to
      :command:`FetchContent_Declare` for ``<name>``.  If ``SOURCE_DIR`` or
      ``BINARY_DIR`` were not part of the original declared arguments, they
      will be added with their default values.
      If :variable:`FETCHCONTENT_TRY_FIND_PACKAGE_MODE` was set to ``NEVER``
      when the details were declared, any ``FIND_PACKAGE_ARGS`` will be
      omitted.  The ``OVERRIDE_FIND_PACKAGE`` keyword is also always omitted.
      If the provider fulfilled the request, ``FetchContent_MakeAvailable()``
      will consider that dependency handled, skip the remaining steps below
      and move on to the next dependency in the list.

  * .. versionadded:: 3.24

      If permitted, :command:`find_package(<name> [<args>...]) <find_package>`
      will be called, where ``<args>...`` may be provided by the
      ``FIND_PACKAGE_ARGS`` option in :command:`FetchContent_Declare`.
      The value of the :variable:`FETCHCONTENT_TRY_FIND_PACKAGE_MODE` variable
      at the time :command:`FetchContent_Declare` was called determines whether
      ``FetchContent_MakeAvailable()`` can call :command:`find_package`.
      If the :variable:`CMAKE_FIND_PACKAGE_TARGETS_GLOBAL` variable is set to
      true when ``FetchContent_MakeAvailable()`` is called, it still affects
      any imported targets created when that in turn calls
      :command:`find_package`, even if that variable was false when the
      corresponding details were declared.

  If the dependency was not satisfied by a provider or a
  :command:`find_package` call, ``FetchContent_MakeAvailable()`` then uses
  the following logic to make the dependency available:

  * If the dependency has already been populated earlier in this run, set
    the ``<lowercaseName>_POPULATED``, ``<lowercaseName>_SOURCE_DIR`` and
    ``<lowercaseName>_BINARY_DIR`` variables in the same way as a call to
    :command:`FetchContent_GetProperties`, then skip the remaining steps
    below and move on to the next dependency in the list.

  * Call :command:`FetchContent_Populate` to populate the dependency using
    the details recorded by an earlier call to :command:`FetchContent_Declare`.
    Halt with a fatal error if no such details have been recorded.
    :variable:`FETCHCONTENT_SOURCE_DIR_<uppercaseName>` can be used to override
    the declared details and use content provided at the specified location
    instead.

  * .. versionadded:: 3.24

      Ensure the :variable:`CMAKE_FIND_PACKAGE_REDIRECTS_DIR` directory
      contains a ``<lowercaseName>-config.cmake`` and a
      ``<lowercaseName>-config-version.cmake`` file (or equivalently
      ``<name>Config.cmake`` and ``<name>ConfigVersion.cmake``).
      The directory that the :variable:`CMAKE_FIND_PACKAGE_REDIRECTS_DIR`
      variable points to is cleared at the start of every CMake run.
      If no config file exists when :command:`FetchContent_Populate` returns,
      a minimal one will be written which :command:`includes <include>` any
      ``<lowercaseName>-extra.cmake`` or ``<name>Extra.cmake`` file with the
      ``OPTIONAL`` flag (so the files can be missing and won't generate a
      warning).  Similarly, if no config version file exists, a very simple
      one will be written which sets ``PACKAGE_VERSION_COMPATIBLE`` and
      ``PACKAGE_VERSION_EXACT`` to true.  This ensures all future calls to
      :command:`find_package()` for the dependency will use the redirected
      config file, regardless of any version requirements.
      CMake cannot automatically determine an arbitrary dependency's version,
      so it cannot set ``PACKAGE_VERSION``.
      When a dependency is pulled in via :command:`add_subdirectory` in the
      next step, it may choose to overwrite the generated config version file
      in :variable:`CMAKE_FIND_PACKAGE_REDIRECTS_DIR` with one that also sets
      ``PACKAGE_VERSION``.
      The dependency may also write a ``<lowercaseName>-extra.cmake`` or
      ``<name>Extra.cmake`` file to perform custom processing or define any
      variables that their normal (installed) package config file would
      otherwise usually define (many projects don't do any custom processing
      or set any variables and therefore have no need to do this).
      If required, the main project can write these files instead if the
      dependency project doesn't do so.  This allows the main project to
      add missing details from older dependencies that haven't or can't be
      updated to support this functionality.
      See `Integrating With find_package()`_ for examples.

  * If the top directory of the populated content contains a ``CMakeLists.txt``
    file, call :command:`add_subdirectory` to add it to the main build.
    It is not an error for there to be no ``CMakeLists.txt`` file, which
    allows the command to be used for dependencies that make downloaded
    content available at a known location, but which do not need or support
    being added directly to the build.

    .. versionadded:: 3.18
      The ``SOURCE_SUBDIR`` option can be given in the declared details to
      look somewhere below the top directory instead (i.e. the same way that
      ``SOURCE_SUBDIR`` is used by the :command:`ExternalProject_Add`
      command).  The path provided with ``SOURCE_SUBDIR`` must be relative
      and will be treated as relative to the top directory.  It can also
      point to a directory that does not contain a ``CMakeLists.txt`` file
      or even to a directory that doesn't exist.  This can be used to avoid
      adding a project that contains a ``CMakeLists.txt`` file in its top
      directory.

    .. versionadded:: 3.25
      If the ``SYSTEM`` keyword was included in the call to
      :command:`FetchContent_Declare`, the ``SYSTEM`` keyword will be
      added to the :command:`add_subdirectory` command as well.

  Projects should aim to declare the details of all dependencies they might
  use before they call ``FetchContent_MakeAvailable()`` for any of them.
  This ensures that if any of the dependencies are also sub-dependencies of
  one or more of the others, the main project still controls the details
  that will be used (because it will declare them first before the
  dependencies get a chance to).  In the following code samples, assume that
  the ``uses_other`` dependency also uses ``FetchContent`` to add the ``other``
  dependency internally:

  .. code-block:: cmake

    # WRONG: Should declare all details first
    FetchContent_Declare(uses_other ...)
    FetchContent_MakeAvailable(uses_other)

    FetchContent_Declare(other ...)    # Will be ignored, uses_other beat us to it
    FetchContent_MakeAvailable(other)  # Would use details declared by uses_other

  .. code-block:: cmake

    # CORRECT: All details declared first, so they will take priority
    FetchContent_Declare(uses_other ...)
    FetchContent_Declare(other ...)
    FetchContent_MakeAvailable(uses_other other)

  Note that :variable:`CMAKE_VERIFY_INTERFACE_HEADER_SETS` is explicitly set
  to false upon entry to ``FetchContent_MakeAvailable()``, and is restored to
  its original value before the command returns.  Developers typically only
  want to verify header sets from the main project, not those from any
  dependencies.  This local manipulation of the
  :variable:`CMAKE_VERIFY_INTERFACE_HEADER_SETS` variable provides that
  intuitive behavior.  You can use variables like
  :variable:`CMAKE_PROJECT_INCLUDE` or
  :variable:`CMAKE_PROJECT_<PROJECT-NAME>_INCLUDE` to turn verification back
  on for all or some dependencies.  You can also set the
  :prop_tgt:`VERIFY_INTERFACE_HEADER_SETS` property of individual targets.

.. command:: FetchContent_Populate

  .. note::
    Where possible, prefer to use :command:`FetchContent_MakeAvailable`
    instead of implementing population manually with this command.

  .. code-block:: cmake

    FetchContent_Populate(<name>)

  In most cases, the only argument given to ``FetchContent_Populate()`` is the
  ``<name>``.  When used this way, the command assumes the content details have
  been recorded by an earlier call to :command:`FetchContent_Declare`.  The
  details are stored in a global property, so they are unaffected by things
  like variable or directory scope.  Therefore, it doesn't matter where in the
  project the details were previously declared, as long as they have been
  declared before the call to ``FetchContent_Populate()``.  Those saved details
  are then used to construct a call to :command:`ExternalProject_Add` in a
  private sub-build to perform the content population immediately.  The
  implementation of ``ExternalProject_Add()`` ensures that if the content has
  already been populated in a previous CMake run, that content will be reused
  rather than repopulating them again.  For the common case where population
  involves downloading content, the cost of the download is only paid once.

  An internal global property records when a particular content population
  request has been processed.  If ``FetchContent_Populate()`` is called more
  than once for the same content name within a configure run, the second call
  will halt with an error.  Projects can and should check whether content
  population has already been processed with the
  :command:`FetchContent_GetProperties` command before calling
  ``FetchContent_Populate()``.

  ``FetchContent_Populate()`` will set three variables in the scope of the
  caller:

  ``<lowercaseName>_POPULATED``
    This will always be set to ``TRUE`` by the call.

  ``<lowercaseName>_SOURCE_DIR``
    The location where the populated content can be found upon return.

  ``<lowercaseName>_BINARY_DIR``
    A directory intended for use as a corresponding build directory.

  The main use case for the ``<lowercaseName>_SOURCE_DIR`` and
  ``<lowercaseName>_BINARY_DIR`` variables is to call
  :command:`add_subdirectory` immediately after population:

  .. code-block:: cmake

    FetchContent_Populate(FooBar)
    add_subdirectory(${foobar_SOURCE_DIR} ${foobar_BINARY_DIR})

  The values of the three variables can also be retrieved from anywhere in the
  project hierarchy using the :command:`FetchContent_GetProperties` command.

  The ``FetchContent_Populate()`` command also supports a syntax allowing the
  content details to be specified directly rather than using any saved
  details.  This is more low-level and use of this form is generally to be
  avoided in favor of using saved content details as outlined above.
  Nevertheless, in certain situations it can be useful to invoke the content
  population as an isolated operation (typically as part of implementing some
  other higher level feature or when using CMake in script mode):

  .. code-block:: cmake

    FetchContent_Populate(
      <name>
      [QUIET]
      [SUBBUILD_DIR <subBuildDir>]
      [SOURCE_DIR <srcDir>]
      [BINARY_DIR <binDir>]
      ...
    )

  This form has a number of key differences to that where only ``<name>`` is
  provided:

  - All required population details are assumed to have been provided directly
    in the call to ``FetchContent_Populate()``. Any saved details for
    ``<name>`` are ignored.
  - No check is made for whether content for ``<name>`` has already been
    populated.
  - No global property is set to record that the population has occurred.
  - No global properties record the source or binary directories used for the
    populated content.
  - The ``FETCHCONTENT_FULLY_DISCONNECTED`` and
    ``FETCHCONTENT_UPDATES_DISCONNECTED`` cache variables are ignored.

  The ``<lowercaseName>_SOURCE_DIR`` and ``<lowercaseName>_BINARY_DIR``
  variables are still returned to the caller, but since these locations are
  not stored as global properties when this form is used, they are only
  available to the calling scope and below rather than the entire project
  hierarchy.  No ``<lowercaseName>_POPULATED`` variable is set in the caller's
  scope with this form.

  The supported options for ``FetchContent_Populate()`` are the same as those
  for :command:`FetchContent_Declare()`.  Those few options shown just
  above are either specific to ``FetchContent_Populate()`` or their behavior is
  slightly modified from how :command:`ExternalProject_Add` treats them:

  ``QUIET``
    The ``QUIET`` option can be given to hide the output associated with
    populating the specified content.  If the population fails, the output will
    be shown regardless of whether this option was given or not so that the
    cause of the failure can be diagnosed.  The global ``FETCHCONTENT_QUIET``
    cache variable has no effect on ``FetchContent_Populate()`` calls where the
    content details are provided directly.

  ``SUBBUILD_DIR``
    The ``SUBBUILD_DIR`` argument can be provided to change the location of the
    sub-build created to perform the population.  The default value is
    ``${CMAKE_CURRENT_BINARY_DIR}/<lowercaseName>-subbuild`` and it would be
    unusual to need to override this default.  If a relative path is specified,
    it will be interpreted as relative to :variable:`CMAKE_CURRENT_BINARY_DIR`.
    This option should not be confused with the ``SOURCE_SUBDIR`` option which
    only affects the :command:`FetchContent_MakeAvailable` command.

  ``SOURCE_DIR``, ``BINARY_DIR``
    The ``SOURCE_DIR`` and ``BINARY_DIR`` arguments are supported by
    :command:`ExternalProject_Add`, but different default values are used by
    ``FetchContent_Populate()``.  ``SOURCE_DIR`` defaults to
    ``${CMAKE_CURRENT_BINARY_DIR}/<lowercaseName>-src`` and ``BINARY_DIR``
    defaults to ``${CMAKE_CURRENT_BINARY_DIR}/<lowercaseName>-build``.
    If a relative path is specified, it will be interpreted as relative to
    :variable:`CMAKE_CURRENT_BINARY_DIR`.

  In addition to the above explicit options, any other unrecognized options are
  passed through unmodified to :command:`ExternalProject_Add` to perform the
  download, patch and update steps.  The following options are explicitly
  prohibited (they are disabled by the ``FetchContent_Populate()`` command):

  - ``CONFIGURE_COMMAND``
  - ``BUILD_COMMAND``
  - ``INSTALL_COMMAND``
  - ``TEST_COMMAND``

  If using ``FetchContent_Populate()`` within CMake's script mode, be aware
  that the implementation sets up a sub-build which therefore requires a CMake
  generator and build tool to be available. If these cannot be found by
  default, then the :variable:`CMAKE_GENERATOR` and/or
  :variable:`CMAKE_MAKE_PROGRAM` variables will need to be set appropriately
  on the command line invoking the script.

  .. versionadded:: 3.18
    Added support for the ``DOWNLOAD_NO_EXTRACT`` option.

.. command:: FetchContent_GetProperties

  When using saved content details, a call to
  :command:`FetchContent_MakeAvailable` or :command:`FetchContent_Populate`
  records information in global properties which can be queried at any time.
  This information may include the source and binary directories associated with
  the content and also whether or not the content population has been processed
  during the current configure run.

  .. code-block:: cmake

    FetchContent_GetProperties(
      <name>
      [SOURCE_DIR <srcDirVar>]
      [BINARY_DIR <binDirVar>]
      [POPULATED <doneVar>]
    )

  The ``SOURCE_DIR``, ``BINARY_DIR`` and ``POPULATED`` options can be used to
  specify which properties should be retrieved.  Each option accepts a value
  which is the name of the variable in which to store that property.  Most of
  the time though, only ``<name>`` is given, in which case the call will then
  set the same variables as a call to
  :command:`FetchContent_MakeAvailable(name) <FetchContent_MakeAvailable>` or
  :command:`FetchContent_Populate(name) <FetchContent_Populate>`.
  Note that the ``SOURCE_DIR`` and ``BINARY_DIR`` values can be empty if the
  call is fulfilled by a :ref:`dependency provider <dependency_providers>`.

  This command is rarely needed when using
  :command:`FetchContent_MakeAvailable`.  It is more commonly used as part of
  implementing the following pattern with :command:`FetchContent_Populate`,
  which ensures that the relevant variables will always be defined regardless
  of whether or not the population has been performed elsewhere in the project
  already:

  .. code-block:: cmake

    # Check if population has already been performed
    FetchContent_GetProperties(depname)
    if(NOT depname_POPULATED)
      # Fetch the content using previously declared details
      FetchContent_Populate(depname)

      # Set custom variables, policies, etc.
      # ...

      # Bring the populated content into the build
      add_subdirectory(${depname_SOURCE_DIR} ${depname_BINARY_DIR})
    endif()

.. command:: FetchContent_SetPopulated

  .. versionadded:: 3.24

  .. note::
    This command should only be called by
    :ref:`dependency providers <dependency_providers>`.  Calling it in any
    other context is unsupported and future CMake versions may halt with a
    fatal error in such cases.

  .. code-block:: cmake

    FetchContent_SetPopulated(
      <name>
      [SOURCE_DIR <srcDir>]
      [BINARY_DIR <binDir>]
    )

  If a provider command fulfills a ``FETCHCONTENT_MAKEAVAILABLE_SERIAL``
  request, it must call this function before returning.  The ``SOURCE_DIR``
  and ``BINARY_DIR`` arguments can be used to specify the values that
  :command:`FetchContent_GetProperties` should return for its corresponding
  arguments.  Only provide ``SOURCE_DIR`` and ``BINARY_DIR`` if they have
  the same meaning as if they had been populated by the built-in
  :command:`FetchContent_MakeAvailable` implementation.


Variables
^^^^^^^^^

A number of cache variables can influence the behavior where details from a
:command:`FetchContent_Declare` call are used to populate content.

.. note::
  All of these variables are intended for the developer to customize behavior.
  They should not normally be set by the project.

.. variable:: FETCHCONTENT_BASE_DIR

  In most cases, the saved details do not specify any options relating to the
  directories to use for the internal sub-build, final source and build areas.
  It is generally best to leave these decisions up to the ``FetchContent``
  module to handle on the project's behalf.  The ``FETCHCONTENT_BASE_DIR``
  cache variable controls the point under which all content population
  directories are collected, but in most cases, developers would not need to
  change this.  The default location is ``${CMAKE_BINARY_DIR}/_deps``, but if
  developers change this value, they should aim to keep the path short and
  just below the top level of the build tree to avoid running into path
  length problems on Windows.

.. variable:: FETCHCONTENT_QUIET

  The logging output during population can be quite verbose, making the
  configure stage quite noisy.  This cache option (``ON`` by default) hides
  all population output unless an error is encountered.  If experiencing
  problems with hung downloads, temporarily switching this option off may
  help diagnose which content population is causing the issue.

.. variable:: FETCHCONTENT_FULLY_DISCONNECTED

  When this option is enabled, no attempt is made to download or update
  any content.  It is assumed that all content has already been populated in
  a previous run or the source directories have been pointed at existing
  contents the developer has provided manually (using options described
  further below).  When the developer knows that no changes have been made to
  any content details, turning this option ``ON`` can significantly speed up
  the configure stage.  It is ``OFF`` by default.

.. variable:: FETCHCONTENT_UPDATES_DISCONNECTED

  This is a less severe download/update control compared to
  :variable:`FETCHCONTENT_FULLY_DISCONNECTED`.  Instead of bypassing all
  download and update logic, ``FETCHCONTENT_UPDATES_DISCONNECTED`` only
  disables the update stage.  Therefore, if content has not been downloaded
  previously, it will still be downloaded when this option is enabled.
  This can speed up the configure stage, but not as much as
  :variable:`FETCHCONTENT_FULLY_DISCONNECTED`.  It is ``OFF`` by default.

.. variable:: FETCHCONTENT_TRY_FIND_PACKAGE_MODE

  .. versionadded:: 3.24

  This variable modifies the details that :command:`FetchContent_Declare`
  records for a given dependency.  While it ultimately controls the behavior
  of :command:`FetchContent_MakeAvailable`, it is the variable's value when
  :command:`FetchContent_Declare` is called that gets used.  It makes no
  difference what the variable is set to when
  :command:`FetchContent_MakeAvailable` is called.  Since the variable should
  only be set by the user and not by projects directly, it will typically have
  the same value throughout anyway, so this distinction is not usually
  noticeable.

  ``FETCHCONTENT_TRY_FIND_PACKAGE_MODE`` ultimately controls whether
  :command:`FetchContent_MakeAvailable` is allowed to call
  :command:`find_package` to satisfy a dependency.  The variable can be set
  to one of the following values:

  ``OPT_IN``
    :command:`FetchContent_MakeAvailable` will only call
    :command:`find_package` if the :command:`FetchContent_Declare` call
    included a ``FIND_PACKAGE_ARGS`` keyword.  This is also the default
    behavior if ``FETCHCONTENT_TRY_FIND_PACKAGE_MODE`` is not set.

  ``ALWAYS``
    :command:`find_package` can be called by
    :command:`FetchContent_MakeAvailable` regardless of whether the
    :command:`FetchContent_Declare` call included a ``FIND_PACKAGE_ARGS``
    keyword or not.  If no ``FIND_PACKAGE_ARGS`` keyword was given, the
    behavior will be as though ``FIND_PACKAGE_ARGS`` had been provided,
    with no additional arguments after it.

  ``NEVER``
    :command:`FetchContent_MakeAvailable` will not call
    :command:`find_package`.  Any ``FIND_PACKAGE_ARGS`` given to the
    :command:`FetchContent_Declare` call will be ignored.

  As a special case, if the :variable:`FETCHCONTENT_SOURCE_DIR_<uppercaseName>`
  variable has a non-empty value for a dependency, it is assumed that the
  user is overriding all other methods of making that dependency available.
  ``FETCHCONTENT_TRY_FIND_PACKAGE_MODE`` will have no effect on that
  dependency and :command:`FetchContent_MakeAvailable` will not try to call
  :command:`find_package` for it.

In addition to the above, the following variables are also defined for each
content name:

.. variable:: FETCHCONTENT_SOURCE_DIR_<uppercaseName>

  If this is set, no download or update steps are performed for the specified
  content and the ``<lowercaseName>_SOURCE_DIR`` variable returned to the
  caller is pointed at this location.  This gives developers a way to have a
  separate checkout of the content that they can modify freely without
  interference from the build.  The build simply uses that existing source,
  but it still defines ``<lowercaseName>_BINARY_DIR`` to point inside its own
  build area.  Developers are strongly encouraged to use this mechanism rather
  than editing the sources populated in the default location, as changes to
  sources in the default location can be lost when content population details
  are changed by the project.

.. variable:: FETCHCONTENT_UPDATES_DISCONNECTED_<uppercaseName>

  This is the per-content equivalent of
  :variable:`FETCHCONTENT_UPDATES_DISCONNECTED`.  If the global option or
  this option is ``ON``, then updates will be disabled for the named content.
  Disabling updates for individual content can be useful for content whose
  details rarely change, while still leaving other frequently changing content
  with updates enabled.

.. _`fetch-content-examples`:

Examples
^^^^^^^^

Typical Case
""""""""""""

This first fairly straightforward example ensures that some popular testing
frameworks are available to the main build:

.. code-block:: cmake

  include(FetchContent)
  FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://github.com/google/googletest.git
    GIT_TAG        703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
  )
  FetchContent_Declare(
    Catch2
    GIT_REPOSITORY https://github.com/catchorg/Catch2.git
    GIT_TAG        605a34765aa5d5ecbf476b4598a862ada971b0cc # v3.0.1
  )

  # After the following call, the CMake targets defined by googletest and
  # Catch2 will be available to the rest of the build
  FetchContent_MakeAvailable(googletest Catch2)

.. _FetchContent-find_package-integration-examples:

Integrating With find_package()
"""""""""""""""""""""""""""""""

For the previous example, if the user wanted to try to find ``googletest``
and ``Catch2`` via :command:`find_package` first before trying to download
and build them from source, they could set the
:variable:`FETCHCONTENT_TRY_FIND_PACKAGE_MODE` variable to ``ALWAYS``.
This would also affect any other calls to :command:`FetchContent_Declare`
throughout the project, which might not be acceptable.  The behavior can be
enabled for just these two dependencies instead by adding ``FIND_PACKAGE_ARGS``
to the declared details and leaving
:variable:`FETCHCONTENT_TRY_FIND_PACKAGE_MODE` unset, or set to ``OPT_IN``:

.. code-block:: cmake

  include(FetchContent)
  FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://github.com/google/googletest.git
    GIT_TAG        703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
    FIND_PACKAGE_ARGS NAMES GTest
  )
  FetchContent_Declare(
    Catch2
    GIT_REPOSITORY https://github.com/catchorg/Catch2.git
    GIT_TAG        605a34765aa5d5ecbf476b4598a862ada971b0cc # v3.0.1
    FIND_PACKAGE_ARGS
  )

  # This will try calling find_package() first for both dependencies
  FetchContent_MakeAvailable(googletest Catch2)

For ``Catch2``, no additional arguments to :command:`find_package` are needed,
so no additional arguments are provided after the ``FIND_PACKAGE_ARGS``
keyword.  For ``googletest``, its package is more commonly called ``GTest``,
so arguments are added to support it being found by that name.

If the user wanted to disable :command:`FetchContent_MakeAvailable` from
calling :command:`find_package` for any dependency, even if it provided
``FIND_PACKAGE_ARGS`` in its declared details, they could set
:variable:`FETCHCONTENT_TRY_FIND_PACKAGE_MODE` to ``NEVER``.

If the project wanted to indicate that these two dependencies should be
downloaded and built from source and that :command:`find_package` calls
should be redirected to use the built dependencies, the
``OVERRIDE_FIND_PACKAGE`` option should be used when declaring the content
details:

.. code-block:: cmake

  include(FetchContent)
  FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://github.com/google/googletest.git
    GIT_TAG        703bd9caab50b139428cea1aaff9974ebee5742e # release-1.10.0
    OVERRIDE_FIND_PACKAGE
  )
  FetchContent_Declare(
    Catch2
    GIT_REPOSITORY https://github.com/catchorg/Catch2.git
    GIT_TAG        605a34765aa5d5ecbf476b4598a862ada971b0cc # v3.0.1
    OVERRIDE_FIND_PACKAGE
  )

  # The following will automatically forward through to FetchContent_MakeAvailable()
  find_package(googletest)
  find_package(Catch2)

CMake provides a FindGTest module which defines some variables that older
projects may use instead of linking to the imported targets.  To support
those cases, we can provide an extra file.  In keeping with the
"first to define, wins" philosophy of ``FetchContent``, we only write out
that file if something else hasn't already done so.

.. code-block:: cmake

  FetchContent_MakeAvailable(googletest)

  if(NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/googletest-extra.cmake AND
     NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/googletestExtra.cmake)
    file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/googletest-extra.cmake
  [=[
  if("${GTEST_LIBRARIES}" STREQUAL "" AND TARGET GTest::gtest)
    set(GTEST_LIBRARIES GTest::gtest)
  endif()
  if("${GTEST_MAIN_LIBRARIES}" STREQUAL "" AND TARGET GTest::gtest_main)
    set(GTEST_MAIN_LIBRARIES GTest::gtest_main)
  endif()
  if("${GTEST_BOTH_LIBRARIES}" STREQUAL "")
    set(GTEST_BOTH_LIBRARIES ${GTEST_LIBRARIES} ${GTEST_MAIN_LIBRARIES})
  endif()
  ]=])
  endif()

Projects will also likely be using ``find_package(GTest)`` rather than
``find_package(googletest)``, but it is possible to make use of the
:variable:`CMAKE_FIND_PACKAGE_REDIRECTS_DIR` area to pull in the latter as
a dependency of the former.  This is likely to be sufficient to satisfy
a typical ``find_package(GTest)`` call.

.. code-block:: cmake

  FetchContent_MakeAvailable(googletest)

  if(NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-config.cmake AND
     NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/GTestConfig.cmake)
    file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-config.cmake
  [=[
  include(CMakeFindDependencyMacro)
  find_dependency(googletest)
  ]=])
  endif()

  if(NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-config-version.cmake AND
     NOT EXISTS ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/GTestConfigVersion.cmake)
    file(WRITE ${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/gtest-config-version.cmake
  [=[
  include(${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/googletest-config-version.cmake OPTIONAL)
  if(NOT PACKAGE_VERSION_COMPATIBLE)
    include(${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/googletestConfigVersion.cmake OPTIONAL)
  endif()
  ]=])
  endif()

Overriding Where To Find CMakeLists.txt
"""""""""""""""""""""""""""""""""""""""

If the sub-project's ``CMakeLists.txt`` file is not at the top level of its
source tree, the ``SOURCE_SUBDIR`` option can be used to tell ``FetchContent``
where to find it.  The following example shows how to use that option, and
it also sets a variable which is meaningful to the subproject before pulling
it into the main build (set as an ``INTERNAL`` cache variable to avoid
problems with policy :policy:`CMP0077`):

.. code-block:: cmake

  include(FetchContent)
  FetchContent_Declare(
    protobuf
    GIT_REPOSITORY https://github.com/protocolbuffers/protobuf.git
    GIT_TAG        ae50d9b9902526efd6c7a1907d09739f959c6297 # v3.15.0
    SOURCE_SUBDIR  cmake
  )
  set(protobuf_BUILD_TESTS OFF CACHE INTERNAL "")
  FetchContent_MakeAvailable(protobuf)

Complex Dependency Hierarchies
""""""""""""""""""""""""""""""

In more complex project hierarchies, the dependency relationships can be more
complicated.  Consider a hierarchy where ``projA`` is the top level project and
it depends directly on projects ``projB`` and ``projC``.  Both ``projB`` and
``projC`` can be built standalone and they also both depend on another project
``projD``.  ``projB`` additionally depends on ``projE``.  This example assumes
that all five projects are available on a company git server.  The
``CMakeLists.txt`` of each project might have sections like the following:

.. code-block:: cmake
  :caption: *projA*

  include(FetchContent)
  FetchContent_Declare(
    projB
    GIT_REPOSITORY git@mycompany.com:git/projB.git
    GIT_TAG        4a89dc7e24ff212a7b5167bef7ab079d
  )
  FetchContent_Declare(
    projC
    GIT_REPOSITORY git@mycompany.com:git/projC.git
    GIT_TAG        4ad4016bd1d8d5412d135cf8ceea1bb9
  )
  FetchContent_Declare(
    projD
    GIT_REPOSITORY git@mycompany.com:git/projD.git
    GIT_TAG        origin/integrationBranch
  )
  FetchContent_Declare(
    projE
    GIT_REPOSITORY git@mycompany.com:git/projE.git
    GIT_TAG        v2.3-rc1
  )

  # Order is important, see notes in the discussion further below
  FetchContent_MakeAvailable(projD projB projC)


.. code-block:: cmake
  :caption: *projB*

  include(FetchContent)
  FetchContent_Declare(
    projD
    GIT_REPOSITORY git@mycompany.com:git/projD.git
    GIT_TAG        20b415f9034bbd2a2e8216e9a5c9e632
  )
  FetchContent_Declare(
    projE
    GIT_REPOSITORY git@mycompany.com:git/projE.git
    GIT_TAG        68e20f674a48be38d60e129f600faf7d
  )

  FetchContent_MakeAvailable(projD projE)


.. code-block:: cmake
  :caption: *projC*

  include(FetchContent)
  FetchContent_Declare(
    projD
    GIT_REPOSITORY git@mycompany.com:git/projD.git
    GIT_TAG        7d9a17ad2c962aa13e2fbb8043fb6b8a
  )

  # This particular version of projD requires workarounds
  FetchContent_GetProperties(projD)
  if(NOT projd_POPULATED)
    FetchContent_Populate(projD)

    # Copy an additional/replacement file into the populated source
    file(COPY someFile.c DESTINATION ${projd_SOURCE_DIR}/src)

    add_subdirectory(${projd_SOURCE_DIR} ${projd_BINARY_DIR})
  endif()

A few key points should be noted in the above:

- ``projB`` and ``projC`` define different content details for ``projD``,
  but ``projA`` also defines a set of content details for ``projD``.
  Because ``projA`` will define them first, the details from ``projB`` and
  ``projC`` will not be used.  The override details defined by ``projA``
  are not required to match either of those from ``projB`` or ``projC``, but
  it is up to the higher level project to ensure that the details it does
  define still make sense for the child projects.
- In the ``projA`` call to :command:`FetchContent_MakeAvailable`, ``projD``
  is listed ahead of ``projB`` and ``projC`` to ensure that ``projA`` is in
  control of how ``projD`` is populated.
- While ``projA`` defines content details for ``projE``, it does not need
  to explicitly call ``FetchContent_MakeAvailable(projE)`` or
  ``FetchContent_Populate(projD)`` itself.  Instead, it leaves that to the
  child ``projB``.  For higher level projects, it is often enough to just
  define the override content details and leave the actual population to the
  child projects.  This saves repeating the same thing at each level of the
  project hierarchy unnecessarily.

Populating Content Without Adding It To The Build
"""""""""""""""""""""""""""""""""""""""""""""""""

Projects don't always need to add the populated content to the build.
Sometimes the project just wants to make the downloaded content available at
a predictable location.  The next example ensures that a set of standard
company toolchain files (and potentially even the toolchain binaries
themselves) is available early enough to be used for that same build.

.. code-block:: cmake

  cmake_minimum_required(VERSION 3.14)

  include(FetchContent)
  FetchContent_Declare(
    mycom_toolchains
    URL  https://intranet.mycompany.com//toolchains_1.3.2.tar.gz
  )
  FetchContent_MakeAvailable(mycom_toolchains)

  project(CrossCompileExample)

The project could be configured to use one of the downloaded toolchains like
so:

.. code-block:: shell

  cmake -DCMAKE_TOOLCHAIN_FILE=_deps/mycom_toolchains-src/toolchain_arm.cmake /path/to/src

When CMake processes the ``CMakeLists.txt`` file, it will download and unpack
the tarball into ``_deps/mycompany_toolchains-src`` relative to the build
directory.  The :variable:`CMAKE_TOOLCHAIN_FILE` variable is not used until
the :command:`project` command is reached, at which point CMake looks for the
named toolchain file relative to the build directory.  Because the tarball has
already been downloaded and unpacked by then, the toolchain file will be in
place, even the very first time that :program:`cmake` is run in the build directory.

Populating Content In CMake Script Mode
"""""""""""""""""""""""""""""""""""""""

This last example demonstrates how one might download and unpack a
firmware tarball using CMake's :manual:`script mode <cmake(1)>`.  The call to
:command:`FetchContent_Populate` specifies all the content details and the
unpacked firmware will be placed in a ``firmware`` directory below the
current working directory.

.. code-block:: cmake
  :caption: :file:`getFirmware.cmake`

  # NOTE: Intended to be run in script mode with cmake -P
  include(FetchContent)
  FetchContent_Populate(
    firmware
    URL        https://mycompany.com/assets/firmware-1.23-arm.tar.gz
    URL_HASH   MD5=68247684da89b608d466253762b0ff11
    SOURCE_DIR firmware
  )

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

include(${CMAKE_CURRENT_LIST_DIR}/ExternalProject/shared_internal_commands.cmake)

#=======================================================================
# Recording and retrieving content details for later population
#=======================================================================

# Internal use, projects must not call this directly. It is
# intended for use by FetchContent_Declare() only.
#
# Sets a content-specific global property (not meant for use
# outside of functions defined here in this file) which can later
# be retrieved using __FetchContent_getSavedDetails() with just the
# same content name. If there is already a value stored in the
# property, it is left unchanged and this call has no effect.
# This allows parent projects to define the content details,
# overriding anything a child project may try to set (properties
# are not cached between runs, so the first thing to set it in a
# build will be in control).
function(__FetchContent_declareDetails contentName)

  string(TOLOWER ${contentName} contentNameLower)
  set(savedDetailsPropertyName "_FetchContent_${contentNameLower}_savedDetails")
  get_property(alreadyDefined GLOBAL PROPERTY ${savedDetailsPropertyName} DEFINED)
  if(alreadyDefined)
    return()
  endif()

  if("${FETCHCONTENT_TRY_FIND_PACKAGE_MODE}" STREQUAL "ALWAYS")
    set(__tryFindPackage TRUE)
    set(__tryFindPackageAllowed TRUE)
  elseif("${FETCHCONTENT_TRY_FIND_PACKAGE_MODE}" STREQUAL "NEVER")
    set(__tryFindPackage FALSE)
    set(__tryFindPackageAllowed FALSE)
  elseif("${FETCHCONTENT_TRY_FIND_PACKAGE_MODE}" STREQUAL "OPT_IN" OR
         NOT DEFINED FETCHCONTENT_TRY_FIND_PACKAGE_MODE)
    set(__tryFindPackage FALSE)
    set(__tryFindPackageAllowed TRUE)
  else()
    message(FATAL_ERROR
      "Unsupported value for FETCHCONTENT_TRY_FIND_PACKAGE_MODE: "
      "${FETCHCONTENT_TRY_FIND_PACKAGE_MODE}"
    )
  endif()

  set(__cmdArgs)
  set(__findPackageArgs)
  set(__sawQuietKeyword NO)
  set(__sawGlobalKeyword NO)
  foreach(__item IN LISTS ARGN)
    if(DEFINED __findPackageArgs)
      # All remaining args are for find_package()
      string(APPEND __findPackageArgs " [==[${__item}]==]")
      if(__item STREQUAL "QUIET")
        set(__sawQuietKeyword YES)
      elseif(__item STREQUAL "GLOBAL")
        set(__sawGlobalKeyword YES)
      endif()
      continue()
    endif()

    # Still processing non-find_package() args
    if(__item STREQUAL "FIND_PACKAGE_ARGS")
      if(__tryFindPackageAllowed)
        set(__tryFindPackage TRUE)
      endif()
      # All arguments after this keyword are for find_package(). Define the
      # variable but with an empty value initially. This allows us to check
      # at the start of the loop whether to store remaining items in this
      # variable or not. Note that there could be no more args, which is still
      # a valid case because we automatically provide ${contentName} as the
      # package name and there may not need to be any further arguments.
      set(__findPackageArgs "")
      continue()  # Don't store this item
    elseif(__item STREQUAL "OVERRIDE_FIND_PACKAGE")
      set(__tryFindPackageAllowed FALSE)
      # Define a separate dedicated property for find_package() to check
      # in its implementation. This will be a placeholder until FetchContent
      # actually does the population. After that, we will have created a
      # stand-in config file that find_package() will pick up instead.
      set(propertyName "_FetchContent_${contentNameLower}_override_find_package")
      define_property(GLOBAL PROPERTY ${propertyName})
      set_property(GLOBAL PROPERTY ${propertyName} TRUE)
    endif()

    string(APPEND __cmdArgs " [==[${__item}]==]")
  endforeach()

  define_property(GLOBAL PROPERTY ${savedDetailsPropertyName})
  cmake_language(EVAL CODE
    "set_property(GLOBAL PROPERTY ${savedDetailsPropertyName} ${__cmdArgs})"
  )

  if(__tryFindPackage AND __tryFindPackageAllowed)
    set(propertyName "_FetchContent_${contentNameLower}_find_package_args")
    define_property(GLOBAL PROPERTY ${propertyName})
    if(NOT __sawQuietKeyword)
      list(INSERT __findPackageArgs 0 QUIET)
    endif()
    if(CMAKE_FIND_PACKAGE_TARGETS_GLOBAL AND NOT __sawGlobalKeyword)
      list(APPEND __findPackageArgs GLOBAL)
    endif()
    cmake_language(EVAL CODE
      "set_property(GLOBAL PROPERTY ${propertyName} ${__findPackageArgs})"
    )
  endif()

endfunction()


# Internal use, projects must not call this directly. It is
# intended for use by the FetchContent_Declare() function.
#
# Retrieves details saved for the specified content in an
# earlier call to __FetchContent_declareDetails().
function(__FetchContent_getSavedDetails contentName outVar)

  string(TOLOWER ${contentName} contentNameLower)
  set(propertyName "_FetchContent_${contentNameLower}_savedDetails")
  get_property(alreadyDefined GLOBAL PROPERTY ${propertyName} DEFINED)
  if(NOT alreadyDefined)
    message(FATAL_ERROR "No content details recorded for ${contentName}")
  endif()
  get_property(propertyValue GLOBAL PROPERTY ${propertyName})
  set(${outVar} "${propertyValue}" PARENT_SCOPE)

endfunction()


# Saves population details of the content, sets defaults for the
# SOURCE_DIR and BUILD_DIR.
function(FetchContent_Declare contentName)

  # Always check this even if we won't save these details.
  # This helps projects catch errors earlier.
  # Avoid using if(... IN_LIST ...) so we don't have to alter policy settings
  list(FIND ARGN OVERRIDE_FIND_PACKAGE index_OVERRIDE_FIND_PACKAGE)
  list(FIND ARGN FIND_PACKAGE_ARGS index_FIND_PACKAGE_ARGS)
  if(index_OVERRIDE_FIND_PACKAGE GREATER_EQUAL 0 AND
     index_FIND_PACKAGE_ARGS GREATER_EQUAL 0)
    message(FATAL_ERROR
      "Cannot specify both OVERRIDE_FIND_PACKAGE and FIND_PACKAGE_ARGS "
      "when declaring details for ${contentName}"
    )
  endif()

  # Because we are only looking for a subset of the supported keywords, we
  # cannot check for multi-value arguments with this method. We will have to
  # handle the URL keyword differently.
  set(oneValueArgs
    GIT_REPOSITORY
    SVN_REPOSITORY
    DOWNLOAD_NO_EXTRACT
    DOWNLOAD_EXTRACT_TIMESTAMP
    BINARY_DIR
    SOURCE_DIR
  )

  cmake_parse_arguments(PARSE_ARGV 1 ARG "" "${oneValueArgs}" "")

  string(TOLOWER ${contentName} contentNameLower)

  if(NOT ARG_BINARY_DIR)
    set(ARG_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build")
  endif()

  if(NOT ARG_SOURCE_DIR)
    set(ARG_SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src")
  endif()

  if(ARG_GIT_REPOSITORY)
    # We resolve the GIT_REPOSITORY here so that we get the right parent in the
    # remote selection logic. In the sub-build, ExternalProject_Add() would see
    # the private sub-build directory as the parent project, but the parent
    # project should be the one that called FetchContent_Declare(). We resolve
    # a relative repo here so that the sub-build's ExternalProject_Add() only
    # ever sees a non-relative repo.
    # Since these checks may be non-trivial on some platforms (notably Windows),
    # don't perform them if we won't be using these details. This also allows
    # projects to override calls with relative URLs when they have checked out
    # the parent project in an unexpected way, such as from a mirror or fork.
    set(savedDetailsPropertyName "_FetchContent_${contentNameLower}_savedDetails")
    get_property(alreadyDefined GLOBAL PROPERTY ${savedDetailsPropertyName} DEFINED)
    if(NOT alreadyDefined)
      cmake_policy(GET CMP0150 cmp0150
        PARENT_SCOPE # undocumented, do not use outside of CMake
      )
      _ep_resolve_git_remote(_resolved_git_repository
        "${ARG_GIT_REPOSITORY}" "${cmp0150}" "${FETCHCONTENT_BASE_DIR}"
      )
      set(ARG_GIT_REPOSITORY "${_resolved_git_repository}")
    endif()
  endif()

  if(ARG_SVN_REPOSITORY)
    # Add a hash of the svn repository URL to the source dir. This works
    # around the problem where if the URL changes, the download would
    # fail because it tries to checkout/update rather than switch the
    # old URL to the new one. We limit the hash to the first 7 characters
    # so that the source path doesn't get overly long (which can be a
    # problem on windows due to path length limits).
    string(SHA1 urlSHA ${ARG_SVN_REPOSITORY})
    string(SUBSTRING ${urlSHA} 0 7 urlSHA)
    string(APPEND ARG_SOURCE_DIR "-${urlSHA}")
  endif()

  # The ExternalProject_Add() call in the sub-build won't see the CMP0135
  # policy setting of our caller. Work out if that policy will be needed and
  # explicitly set the relevant option if not already provided. The condition
  # here is essentially an abbreviated version of the logic in
  # ExternalProject's _ep_add_download_command() function.
  if(NOT ARG_DOWNLOAD_NO_EXTRACT AND
     NOT DEFINED ARG_DOWNLOAD_EXTRACT_TIMESTAMP)
    list(FIND ARGN URL urlIndex)
    if(urlIndex GREATER_EQUAL 0)
      math(EXPR urlIndex "${urlIndex} + 1")
      list(LENGTH ARGN numArgs)
      if(urlIndex GREATER_EQUAL numArgs)
        message(FATAL_ERROR
          "URL keyword needs to be followed by at least one URL"
        )
      endif()
      # If we have multiple URLs, none of them are allowed to be local paths.
      # Therefore, we can test just the first URL, and if it is non-local, so
      # will be the others if there are more.
      list(GET ARGN ${urlIndex} firstUrl)
      if(NOT IS_DIRECTORY "${firstUrl}")
        cmake_policy(GET CMP0135 _FETCHCONTENT_CMP0135
          PARENT_SCOPE # undocumented, do not use outside of CMake
        )
        if(_FETCHCONTENT_CMP0135 STREQUAL "")
          message(AUTHOR_WARNING
            "The DOWNLOAD_EXTRACT_TIMESTAMP option was not given and policy "
            "CMP0135 is not set. The policy's OLD behavior will be used. "
            "When using a URL download, the timestamps of extracted files "
            "should preferably be that of the time of extraction, otherwise "
            "code that depends on the extracted contents might not be "
            "rebuilt if the URL changes. The OLD behavior preserves the "
            "timestamps from the archive instead, but this is usually not "
            "what you want. Update your project to the NEW behavior or "
            "specify the DOWNLOAD_EXTRACT_TIMESTAMP option with a value of "
            "true to avoid this robustness issue."
          )
          set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP TRUE)
        elseif(_FETCHCONTENT_CMP0135 STREQUAL "NEW")
          set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP FALSE)
        else()
          set(ARG_DOWNLOAD_EXTRACT_TIMESTAMP TRUE)
        endif()
      endif()
    endif()
  endif()

  # Add back in the keyword args we pulled out and potentially tweaked/added
  foreach(key IN LISTS oneValueArgs)
    if(DEFINED ARG_${key})
      list(PREPEND ARG_UNPARSED_ARGUMENTS ${key} "${ARG_${key}}")
    endif()
  endforeach()

  set(__argsQuoted)
  foreach(__item IN LISTS ARG_UNPARSED_ARGUMENTS)
    string(APPEND __argsQuoted " [==[${__item}]==]")
  endforeach()
  cmake_language(EVAL CODE
    "__FetchContent_declareDetails(${contentNameLower} ${__argsQuoted})"
  )

endfunction()


#=======================================================================
# Set/get whether the specified content has been populated yet.
# The setter also records the source and binary dirs used.
#=======================================================================

# Semi-internal use. Projects must not call this directly. Dependency
# providers must call it if they satisfy a request made with the
# FETCHCONTENT_MAKEAVAILABLE_SERIAL method (that is the only permitted
# place to call it outside of the FetchContent module).
function(FetchContent_SetPopulated contentName)

  cmake_parse_arguments(PARSE_ARGV 1 arg
    ""
    "SOURCE_DIR;BINARY_DIR"
    ""
  )
  if(NOT "${arg_UNPARSED_ARGUMENTS}" STREQUAL "")
    message(FATAL_ERROR "Unsupported arguments: ${arg_UNPARSED_ARGUMENTS}")
  endif()

  string(TOLOWER ${contentName} contentNameLower)
  set(prefix "_FetchContent_${contentNameLower}")

  set(propertyName "${prefix}_sourceDir")
  define_property(GLOBAL PROPERTY ${propertyName})
  if("${arg_SOURCE_DIR}" STREQUAL "")
    # Don't discard a previously provided SOURCE_DIR
    get_property(arg_SOURCE_DIR GLOBAL PROPERTY ${propertyName})
  endif()
  set_property(GLOBAL PROPERTY ${propertyName} "${arg_SOURCE_DIR}")

  set(propertyName "${prefix}_binaryDir")
  define_property(GLOBAL PROPERTY ${propertyName})
  if("${arg_BINARY_DIR}" STREQUAL "")
    # Don't discard a previously provided BINARY_DIR
    get_property(arg_BINARY_DIR GLOBAL PROPERTY ${propertyName})
  endif()
  set_property(GLOBAL PROPERTY ${propertyName} "${arg_BINARY_DIR}")

  set(propertyName "${prefix}_populated")
  define_property(GLOBAL PROPERTY ${propertyName})
  set_property(GLOBAL PROPERTY ${propertyName} TRUE)

endfunction()


# Set variables in the calling scope for any of the retrievable
# properties. If no specific properties are requested, variables
# will be set for all retrievable properties.
#
# This function is intended to also be used by projects as the canonical
# way to detect whether they should call FetchContent_Populate()
# and pull the populated source into the build with add_subdirectory(),
# if they are using the populated content in that way.
function(FetchContent_GetProperties contentName)

  string(TOLOWER ${contentName} contentNameLower)

  set(options "")
  set(oneValueArgs SOURCE_DIR BINARY_DIR POPULATED)
  set(multiValueArgs "")

  cmake_parse_arguments(ARG "${options}" "${oneValueArgs}" "${multiValueArgs}" ${ARGN})

  if(NOT ARG_SOURCE_DIR AND
     NOT ARG_BINARY_DIR AND
     NOT ARG_POPULATED)
    # No specific properties requested, provide them all
    set(ARG_SOURCE_DIR ${contentNameLower}_SOURCE_DIR)
    set(ARG_BINARY_DIR ${contentNameLower}_BINARY_DIR)
    set(ARG_POPULATED  ${contentNameLower}_POPULATED)
  endif()

  set(prefix "_FetchContent_${contentNameLower}")

  if(ARG_SOURCE_DIR)
    set(propertyName "${prefix}_sourceDir")
    get_property(value GLOBAL PROPERTY ${propertyName})
    if(value)
      set(${ARG_SOURCE_DIR} ${value} PARENT_SCOPE)
    endif()
  endif()

  if(ARG_BINARY_DIR)
    set(propertyName "${prefix}_binaryDir")
    get_property(value GLOBAL PROPERTY ${propertyName})
    if(value)
      set(${ARG_BINARY_DIR} ${value} PARENT_SCOPE)
    endif()
  endif()

  if(ARG_POPULATED)
    set(propertyName "${prefix}_populated")
    get_property(value GLOBAL PROPERTY ${propertyName} DEFINED)
    set(${ARG_POPULATED} ${value} PARENT_SCOPE)
  endif()

endfunction()


#=======================================================================
# Performing the population
#=======================================================================

# The value of contentName will always have been lowercased by the caller.
# All other arguments are assumed to be options that are understood by
# ExternalProject_Add(), except for QUIET and SUBBUILD_DIR.
function(__FetchContent_directPopulate contentName)

  set(options
      QUIET
      # SYSTEM has no meaning for ExternalProject, it is only used by us in
      # FetchContent_MakeAvailable(). We need to parse and discard it here.
      SYSTEM
  )
  set(oneValueArgs
      SUBBUILD_DIR
      SOURCE_DIR
      BINARY_DIR
      # We need special processing if DOWNLOAD_NO_EXTRACT is true
      DOWNLOAD_NO_EXTRACT
      # Prevent the following from being passed through
      CONFIGURE_COMMAND
      BUILD_COMMAND
      INSTALL_COMMAND
      TEST_COMMAND
      # We force these to be ON since we are always executing serially
      # and we want all steps to have access to the terminal in case they
      # need input from the command line (e.g. ask for a private key password)
      # or they want to provide timely progress. We silently absorb and
      # discard these if they are set by the caller.
      USES_TERMINAL_DOWNLOAD
      USES_TERMINAL_UPDATE
      USES_TERMINAL_PATCH
  )
  set(multiValueArgs "")

  cmake_parse_arguments(PARSE_ARGV 1 ARG
    "${options}" "${oneValueArgs}" "${multiValueArgs}")

  if(NOT ARG_SUBBUILD_DIR)
    message(FATAL_ERROR "Internal error: SUBBUILD_DIR not set")
  elseif(NOT IS_ABSOLUTE "${ARG_SUBBUILD_DIR}")
    set(ARG_SUBBUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/${ARG_SUBBUILD_DIR}")
  endif()

  if(NOT ARG_SOURCE_DIR)
    message(FATAL_ERROR "Internal error: SOURCE_DIR not set")
  elseif(NOT IS_ABSOLUTE "${ARG_SOURCE_DIR}")
    set(ARG_SOURCE_DIR "${CMAKE_CURRENT_BINARY_DIR}/${ARG_SOURCE_DIR}")
  endif()

  if(NOT ARG_BINARY_DIR)
    message(FATAL_ERROR "Internal error: BINARY_DIR not set")
  elseif(NOT IS_ABSOLUTE "${ARG_BINARY_DIR}")
    set(ARG_BINARY_DIR "${CMAKE_CURRENT_BINARY_DIR}/${ARG_BINARY_DIR}")
  endif()

  # Ensure the caller can know where to find the source and build directories
  # with some convenient variables. Doing this here ensures the caller sees
  # the correct result in the case where the default values are overridden by
  # the content details set by the project.
  set(${contentName}_SOURCE_DIR "${ARG_SOURCE_DIR}" PARENT_SCOPE)
  set(${contentName}_BINARY_DIR "${ARG_BINARY_DIR}" PARENT_SCOPE)

  # The unparsed arguments may contain spaces, so build up ARG_EXTRA
  # in such a way that it correctly substitutes into the generated
  # CMakeLists.txt file with each argument quoted.
  unset(ARG_EXTRA)
  foreach(arg IN LISTS ARG_UNPARSED_ARGUMENTS)
    set(ARG_EXTRA "${ARG_EXTRA} \"${arg}\"")
  endforeach()

  if(ARG_DOWNLOAD_NO_EXTRACT)
    set(ARG_EXTRA "${ARG_EXTRA} DOWNLOAD_NO_EXTRACT YES")
    set(__FETCHCONTENT_COPY_FILE
"
ExternalProject_Get_Property(${contentName}-populate DOWNLOADED_FILE)
get_filename_component(dlFileName \"\${DOWNLOADED_FILE}\" NAME)

ExternalProject_Add_Step(${contentName}-populate copyfile
  COMMAND    \"${CMAKE_COMMAND}\" -E copy_if_different
             \"<DOWNLOADED_FILE>\" \"${ARG_SOURCE_DIR}\"
  DEPENDEES  patch
  DEPENDERS  configure
  BYPRODUCTS \"${ARG_SOURCE_DIR}/\${dlFileName}\"
  COMMENT    \"Copying file to SOURCE_DIR\"
)
")
  else()
    unset(__FETCHCONTENT_COPY_FILE)
  endif()

  # Hide output if requested, but save it to a variable in case there's an
  # error so we can show the output upon failure. When not quiet, don't
  # capture the output to a variable because the user may want to see the
  # output as it happens (e.g. progress during long downloads). Combine both
  # stdout and stderr in the one capture variable so the output stays in order.
  if (ARG_QUIET)
    set(outputOptions
        OUTPUT_VARIABLE capturedOutput
        ERROR_VARIABLE  capturedOutput
    )
  else()
    set(capturedOutput)
    set(outputOptions)
    message(STATUS "Populating ${contentName}")
  endif()

  if(CMAKE_GENERATOR)
    set(subCMakeOpts "-G${CMAKE_GENERATOR}")
    if(CMAKE_GENERATOR_PLATFORM)
      list(APPEND subCMakeOpts "-A${CMAKE_GENERATOR_PLATFORM}")
    endif()
    if(CMAKE_GENERATOR_TOOLSET)
      list(APPEND subCMakeOpts "-T${CMAKE_GENERATOR_TOOLSET}")
    endif()
    if(CMAKE_GENERATOR_INSTANCE)
      list(APPEND subCMakeOpts "-DCMAKE_GENERATOR_INSTANCE:INTERNAL=${CMAKE_GENERATOR_INSTANCE}")
    endif()
    if(CMAKE_MAKE_PROGRAM)
      list(APPEND subCMakeOpts "-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}")
    endif()

    # Override the sub-build's configuration types for multi-config generators.
    # This ensures we are not affected by any custom setting from the project
    # and can always request a known configuration further below.
    get_property(is_multi_config GLOBAL PROPERTY GENERATOR_IS_MULTI_CONFIG)
    if(is_multi_config)
      list(APPEND subCMakeOpts "-DCMAKE_CONFIGURATION_TYPES:STRING=Debug")
    endif()

  else()
    # Likely we've been invoked via CMake's script mode where no
    # generator is set (and hence CMAKE_MAKE_PROGRAM could not be
    # trusted even if provided). We will have to rely on being
    # able to find the default generator and build tool.
    unset(subCMakeOpts)
  endif()

  set(__FETCHCONTENT_CACHED_INFO "")
  set(__passthrough_vars
    CMAKE_EP_GIT_REMOTE_UPDATE_STRATEGY
    CMAKE_TLS_VERIFY
    CMAKE_TLS_CAINFO
    CMAKE_NETRC
    CMAKE_NETRC_FILE
  )
  foreach(var IN LISTS __passthrough_vars)
    if(DEFINED ${var})
      # Embed directly in the generated CMakeLists.txt file to avoid making
      # the cmake command line excessively long. It also makes debugging and
      # testing easier.
      string(APPEND __FETCHCONTENT_CACHED_INFO "set(${var} [==[${${var}}]==])\n")
    endif()
  endforeach()

  # Avoid using if(... IN_LIST ...) so we don't have to alter policy settings
  list(FIND ARG_UNPARSED_ARGUMENTS GIT_REPOSITORY indexResult)
  if(indexResult GREATER_EQUAL 0)
    find_package(Git QUIET)
    string(APPEND __FETCHCONTENT_CACHED_INFO "
# Pass through things we've already detected in the main project to avoid
# paying the cost of redetecting them again in ExternalProject_Add()
set(GIT_EXECUTABLE [==[${GIT_EXECUTABLE}]==])
set(GIT_VERSION_STRING [==[${GIT_VERSION_STRING}]==])
set_property(GLOBAL PROPERTY _CMAKE_FindGit_GIT_EXECUTABLE_VERSION
  [==[${GIT_EXECUTABLE};${GIT_VERSION_STRING}]==]
)
")
  endif()

  # Create and build a separate CMake project to carry out the population.
  # If we've already previously done these steps, they will not cause
  # anything to be updated, so extra rebuilds of the project won't occur.
  # Make sure to pass through CMAKE_MAKE_PROGRAM in case the main project
  # has this set to something not findable on the PATH. We also ensured above
  # that the Debug config will be defined for multi-config generators.
  configure_file("${CMAKE_CURRENT_FUNCTION_LIST_DIR}/FetchContent/CMakeLists.cmake.in"
                 "${ARG_SUBBUILD_DIR}/CMakeLists.txt"
                 @ONLY
  )
  execute_process(
    COMMAND ${CMAKE_COMMAND} ${subCMakeOpts} .
    RESULT_VARIABLE result
    ${outputOptions}
    WORKING_DIRECTORY "${ARG_SUBBUILD_DIR}"
  )
  if(result)
    if(capturedOutput)
      message("${capturedOutput}")
    endif()
    message(FATAL_ERROR "CMake step for ${contentName} failed: ${result}")
  endif()
  execute_process(
    COMMAND ${CMAKE_COMMAND} --build . --config Debug
    RESULT_VARIABLE result
    ${outputOptions}
    WORKING_DIRECTORY "${ARG_SUBBUILD_DIR}"
  )
  if(result)
    if(capturedOutput)
      message("${capturedOutput}")
    endif()
    message(FATAL_ERROR "Build step for ${contentName} failed: ${result}")
  endif()

endfunction()


option(FETCHCONTENT_FULLY_DISCONNECTED   "Disables all attempts to download or update content and assumes source dirs already exist")
option(FETCHCONTENT_UPDATES_DISCONNECTED "Enables UPDATE_DISCONNECTED behavior for all content population")
option(FETCHCONTENT_QUIET                "Enables QUIET option for all content population" ON)
set(FETCHCONTENT_BASE_DIR "${CMAKE_BINARY_DIR}/_deps" CACHE PATH "Directory under which to collect all populated content")

# Populate the specified content using details stored from
# an earlier call to FetchContent_Declare().
function(FetchContent_Populate contentName)

  if(NOT contentName)
    message(FATAL_ERROR "Empty contentName not allowed for FetchContent_Populate()")
  endif()

  string(TOLOWER ${contentName} contentNameLower)

  if(ARGN)
    # This is the direct population form with details fully specified
    # as part of the call, so we already have everything we need
    __FetchContent_directPopulate(
      ${contentNameLower}
      SUBBUILD_DIR "${CMAKE_CURRENT_BINARY_DIR}/${contentNameLower}-subbuild"
      SOURCE_DIR   "${CMAKE_CURRENT_BINARY_DIR}/${contentNameLower}-src"
      BINARY_DIR   "${CMAKE_CURRENT_BINARY_DIR}/${contentNameLower}-build"
      ${ARGN}  # Could override any of the above ..._DIR variables
    )

    # Pass source and binary dir variables back to the caller
    set(${contentNameLower}_SOURCE_DIR "${${contentNameLower}_SOURCE_DIR}" PARENT_SCOPE)
    set(${contentNameLower}_BINARY_DIR "${${contentNameLower}_BINARY_DIR}" PARENT_SCOPE)

    # Don't set global properties, or record that we did this population, since
    # this was a direct call outside of the normal declared details form.
    # We only want to save values in the global properties for content that
    # honors the hierarchical details mechanism so that projects are not
    # robbed of the ability to override details set in nested projects.
    return()
  endif()

  # No details provided, so assume they were saved from an earlier call
  # to FetchContent_Declare(). Do a check that we haven't already
  # populated this content before in case the caller forgot to check.
  FetchContent_GetProperties(${contentName})
  if(${contentNameLower}_POPULATED)
    if("${${contentNameLower}_SOURCE_DIR}" STREQUAL "")
      message(FATAL_ERROR
        "Content ${contentName} already populated by find_package() or a "
        "dependency provider"
      )
    else()
      message(FATAL_ERROR
        "Content ${contentName} already populated in ${${contentNameLower}_SOURCE_DIR}"
      )
    endif()
  endif()

  __FetchContent_getSavedDetails(${contentName} contentDetails)
  if("${contentDetails}" STREQUAL "")
    message(FATAL_ERROR "No details have been set for content: ${contentName}")
  endif()

  string(TOUPPER ${contentName} contentNameUpper)
  set(FETCHCONTENT_SOURCE_DIR_${contentNameUpper}
      "${FETCHCONTENT_SOURCE_DIR_${contentNameUpper}}"
      CACHE PATH "When not empty, overrides where to find pre-populated content for ${contentName}")

  if(FETCHCONTENT_SOURCE_DIR_${contentNameUpper})
    # The source directory has been explicitly provided in the cache,
    # so no population is required. The build directory may still be specified
    # by the declared details though.

    if(NOT IS_ABSOLUTE "${FETCHCONTENT_SOURCE_DIR_${contentNameUpper}}")
      # Don't check this directory because we don't know what location it is
      # expected to be relative to. We can't make this a hard error for backward
      # compatibility reasons.
      message(WARNING "Relative source directory specified. This is not safe, "
        "as it depends on the calling directory scope.\n"
        "  FETCHCONTENT_SOURCE_DIR_${contentNameUpper} --> ${FETCHCONTENT_SOURCE_DIR_${contentNameUpper}}")
    elseif(NOT EXISTS "${FETCHCONTENT_SOURCE_DIR_${contentNameUpper}}")
      message(FATAL_ERROR "Manually specified source directory is missing:\n"
        "  FETCHCONTENT_SOURCE_DIR_${contentNameUpper} --> ${FETCHCONTENT_SOURCE_DIR_${contentNameUpper}}")
    endif()

    set(${contentNameLower}_SOURCE_DIR "${FETCHCONTENT_SOURCE_DIR_${contentNameUpper}}")

    cmake_parse_arguments(savedDetails "" "BINARY_DIR" "" ${contentDetails})

    if(savedDetails_BINARY_DIR)
      set(${contentNameLower}_BINARY_DIR ${savedDetails_BINARY_DIR})
    else()
      set(${contentNameLower}_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build")
    endif()

  elseif(FETCHCONTENT_FULLY_DISCONNECTED)
    # Bypass population and assume source is already there from a previous run.
    # Declared details may override the default source or build directories.

    cmake_parse_arguments(savedDetails "" "SOURCE_DIR;BINARY_DIR" "" ${contentDetails})

    if(savedDetails_SOURCE_DIR)
      set(${contentNameLower}_SOURCE_DIR ${savedDetails_SOURCE_DIR})
    else()
      set(${contentNameLower}_SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src")
    endif()

    if(savedDetails_BINARY_DIR)
      set(${contentNameLower}_BINARY_DIR ${savedDetails_BINARY_DIR})
    else()
      set(${contentNameLower}_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build")
    endif()

  else()
    # Support both a global "disconnect all updates" and a per-content
    # update test (either one being set disables updates for this content).
    option(FETCHCONTENT_UPDATES_DISCONNECTED_${contentNameUpper}
           "Enables UPDATE_DISCONNECTED behavior just for population of ${contentName}")
    if(FETCHCONTENT_UPDATES_DISCONNECTED OR
       FETCHCONTENT_UPDATES_DISCONNECTED_${contentNameUpper})
      set(disconnectUpdates True)
    else()
      set(disconnectUpdates False)
    endif()

    if(FETCHCONTENT_QUIET)
      set(quietFlag QUIET)
    else()
      unset(quietFlag)
    endif()

    set(__detailsQuoted)
    foreach(__item IN LISTS contentDetails)
      if(NOT __item STREQUAL "OVERRIDE_FIND_PACKAGE")
        string(APPEND __detailsQuoted " [==[${__item}]==]")
      endif()
    endforeach()
    cmake_language(EVAL CODE "
      __FetchContent_directPopulate(
        ${contentNameLower}
        ${quietFlag}
        UPDATE_DISCONNECTED ${disconnectUpdates}
        SUBBUILD_DIR \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-subbuild\"
        SOURCE_DIR   \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src\"
        BINARY_DIR   \"${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build\"
        # Put the saved details last so they can override any of the
        # the options we set above (this can include SOURCE_DIR or
        # BUILD_DIR)
        ${__detailsQuoted}
      )"
    )
  endif()

  FetchContent_SetPopulated(
    ${contentName}
    SOURCE_DIR "${${contentNameLower}_SOURCE_DIR}"
    BINARY_DIR "${${contentNameLower}_BINARY_DIR}"
  )

  # Pass variables back to the caller. The variables passed back here
  # must match what FetchContent_GetProperties() sets when it is called
  # with just the content name.
  set(${contentNameLower}_SOURCE_DIR "${${contentNameLower}_SOURCE_DIR}" PARENT_SCOPE)
  set(${contentNameLower}_BINARY_DIR "${${contentNameLower}_BINARY_DIR}" PARENT_SCOPE)
  set(${contentNameLower}_POPULATED  True PARENT_SCOPE)

endfunction()

function(__FetchContent_setupFindPackageRedirection contentName)

  __FetchContent_getSavedDetails(${contentName} contentDetails)

  string(TOLOWER ${contentName} contentNameLower)
  get_property(wantFindPackage GLOBAL PROPERTY
    _FetchContent_${contentNameLower}_find_package_args
    DEFINED
  )

  # Avoid using if(... IN_LIST ...) so we don't have to alter policy settings
  list(FIND contentDetails OVERRIDE_FIND_PACKAGE indexResult)
  if(NOT wantFindPackage AND indexResult EQUAL -1)
    # No find_package() redirection allowed
    return()
  endif()

  # We write out dep-config.cmake and dep-config-version.cmake file name
  # forms here because they are forced to lowercase. FetchContent
  # dependency names are case-insensitive, but find_package() config files
  # are only case-insensitive for the -config and -config-version forms,
  # not the Config and ConfigVersion forms.
  set(inFileDir ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/FetchContent)
  set(configFilePrefix1 "${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/${contentName}Config")
  set(configFilePrefix2 "${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}/${contentNameLower}-config")
  if(NOT EXISTS "${configFilePrefix1}.cmake" AND
    NOT EXISTS "${configFilePrefix2}.cmake")
    configure_file(${inFileDir}/package-config.cmake.in
      "${configFilePrefix2}.cmake" @ONLY
    )
  endif()
  if(NOT EXISTS "${configFilePrefix1}Version.cmake" AND
    NOT EXISTS "${configFilePrefix2}-version.cmake")
    configure_file(${inFileDir}/package-config-version.cmake.in
      "${configFilePrefix2}-version.cmake" @ONLY
    )
  endif()

  # Now that we've created the redirected package config files, prevent
  # find_package() from delegating to FetchContent and let it find these
  # config files through its normal processing.
  set(propertyName "${prefix}_override_find_package")
  set(GLOBAL PROPERTY ${propertyName} FALSE)
  set(${contentName}_DIR "${CMAKE_FIND_PACKAGE_REDIRECTS_DIR}"
    CACHE INTERNAL "Redirected by FetchContent"
  )

endfunction()

# Arguments are assumed to be the names of dependencies that have been
# declared previously and should be populated. It is not an error if
# any of them have already been populated (they will just be skipped in
# that case). The command is implemented as a macro so that the variables
# defined by the FetchContent_GetProperties() and FetchContent_Populate()
# calls will be available to the caller.
macro(FetchContent_MakeAvailable)

  # We must append an item, even if the variable is unset, so prefix its value.
  # We will strip that prefix when we pop the value at the end of the macro.
  list(APPEND __cmake_fcCurrentVarsStack
    "__fcprefix__${CMAKE_VERIFY_INTERFACE_HEADER_SETS}"
  )
  set(CMAKE_VERIFY_INTERFACE_HEADER_SETS FALSE)

  get_property(__cmake_providerCommand GLOBAL PROPERTY
    __FETCHCONTENT_MAKEAVAILABLE_SERIAL_PROVIDER
  )
  foreach(__cmake_contentName IN ITEMS ${ARGV})
    string(TOLOWER ${__cmake_contentName} __cmake_contentNameLower)

    # If user specified FETCHCONTENT_SOURCE_DIR_... for this dependency, that
    # overrides everything else and we shouldn't try to use find_package() or
    # a dependency provider.
    string(TOUPPER ${__cmake_contentName} __cmake_contentNameUpper)
    if("${FETCHCONTENT_SOURCE_DIR_${__cmake_contentNameUpper}}" STREQUAL "")
      # Dependency provider gets first opportunity, but prevent infinite
      # recursion if we are called again for the same thing
      if(NOT "${__cmake_providerCommand}" STREQUAL "" AND
        NOT DEFINED __cmake_fcProvider_${__cmake_contentNameLower})
        message(VERBOSE
          "Trying FETCHCONTENT_MAKEAVAILABLE_SERIAL dependency provider for "
          "${__cmake_contentName}"
        )
        # It's still valid if there are no saved details. The project may have
        # been written to assume a dependency provider is always set and will
        # provide dependencies without having any declared details for them.
        __FetchContent_getSavedDetails(${__cmake_contentName} __cmake_contentDetails)
        set(__cmake_providerArgs
          "FETCHCONTENT_MAKEAVAILABLE_SERIAL"
          "${__cmake_contentName}"
        )
        # Empty arguments must be preserved because of things like
        # GIT_SUBMODULES (see CMP0097)
        foreach(__cmake_item IN LISTS __cmake_contentDetails)
          string(APPEND __cmake_providerArgs " [==[${__cmake_item}]==]")
        endforeach()

        # This property might be defined but empty. As long as it is defined,
        # find_package() can be called.
        get_property(__cmake_addfpargs GLOBAL PROPERTY
          _FetchContent_${contentNameLower}_find_package_args
          DEFINED
        )
        if(__cmake_addfpargs)
          get_property(__cmake_fpargs GLOBAL PROPERTY
            _FetchContent_${contentNameLower}_find_package_args
          )
          string(APPEND __cmake_providerArgs " FIND_PACKAGE_ARGS")
          foreach(__cmake_item IN LISTS __cmake_fpargs)
            string(APPEND __cmake_providerArgs " [==[${__cmake_item}]==]")
          endforeach()
        endif()

        # Calling the provider could lead to FetchContent_MakeAvailable() being
        # called for a nested dependency. That nested call may occur in the
        # current variable scope. We have to save and restore the variables we
        # need preserved.
        list(APPEND __cmake_fcCurrentVarsStack
          ${__cmake_contentName}
          ${__cmake_contentNameLower}
        )

        set(__cmake_fcProvider_${__cmake_contentNameLower} YES)
        cmake_language(EVAL CODE "${__cmake_providerCommand}(${__cmake_providerArgs})")

        list(POP_BACK __cmake_fcCurrentVarsStack
          __cmake_contentNameLower
          __cmake_contentName
        )

        unset(__cmake_fcProvider_${__cmake_contentNameLower})
        unset(__cmake_providerArgs)
        unset(__cmake_addfpargs)
        unset(__cmake_fpargs)
        unset(__cmake_item)
        unset(__cmake_contentDetails)

        FetchContent_GetProperties(${__cmake_contentName})
        if(${__cmake_contentNameLower}_POPULATED)
          continue()
        endif()
      endif()

      # Check if we've been asked to try find_package() first, even if we
      # have already populated this dependency. If we previously tried to
      # use find_package() for this and it succeeded, those things might
      # no longer be in scope, so we have to do it again.
      get_property(__cmake_haveFpArgs GLOBAL PROPERTY
        _FetchContent_${__cmake_contentNameLower}_find_package_args DEFINED
      )
      if(__cmake_haveFpArgs)
        unset(__cmake_haveFpArgs)
        message(VERBOSE "Trying find_package(${__cmake_contentName} ...) before FetchContent")
        get_property(__cmake_fpArgs GLOBAL PROPERTY
          _FetchContent_${__cmake_contentNameLower}_find_package_args
        )

        # This call could lead to FetchContent_MakeAvailable() being called for
        # a nested dependency and it may occur in the current variable scope.
        # We have to save/restore the variables we need to preserve.
        list(APPEND __cmake_fcCurrentNameStack
          ${__cmake_contentName}
          ${__cmake_contentNameLower}
        )
        find_package(${__cmake_contentName} ${__cmake_fpArgs})
        list(POP_BACK __cmake_fcCurrentNameStack
          __cmake_contentNameLower
          __cmake_contentName
        )
        unset(__cmake_fpArgs)

        if(${__cmake_contentName}_FOUND)
          FetchContent_SetPopulated(${__cmake_contentName})
          FetchContent_GetProperties(${__cmake_contentName})
          continue()
        endif()
      endif()
    else()
      unset(__cmake_haveFpArgs)
    endif()

    FetchContent_GetProperties(${__cmake_contentName})
    if(NOT ${__cmake_contentNameLower}_POPULATED)
      FetchContent_Populate(${__cmake_contentName})
      __FetchContent_setupFindPackageRedirection(${__cmake_contentName})

      # Only try to call add_subdirectory() if the populated content
      # can be treated that way. Protecting the call with the check
      # allows this function to be used for projects that just want
      # to ensure the content exists, such as to provide content at
      # a known location. We check the saved details for an optional
      # SOURCE_SUBDIR which can be used in the same way as its meaning
      # for ExternalProject. It won't matter if it was passed through
      # to the ExternalProject sub-build, since it would have been
      # ignored there.
      set(__cmake_srcdir "${${__cmake_contentNameLower}_SOURCE_DIR}")
      __FetchContent_getSavedDetails(${__cmake_contentName} __cmake_contentDetails)
      if("${__cmake_contentDetails}" STREQUAL "")
        message(FATAL_ERROR "No details have been set for content: ${__cmake_contentName}")
      endif()
      cmake_parse_arguments(__cmake_arg "SYSTEM" "SOURCE_SUBDIR" "" ${__cmake_contentDetails})
      if(NOT "${__cmake_arg_SOURCE_SUBDIR}" STREQUAL "")
        string(APPEND __cmake_srcdir "/${__cmake_arg_SOURCE_SUBDIR}")
      endif()

      if(EXISTS ${__cmake_srcdir}/CMakeLists.txt)
        if (__cmake_arg_SYSTEM)
          add_subdirectory(${__cmake_srcdir} ${${__cmake_contentNameLower}_BINARY_DIR} SYSTEM)
        else()
          add_subdirectory(${__cmake_srcdir} ${${__cmake_contentNameLower}_BINARY_DIR})
        endif()
      endif()

      unset(__cmake_srcdir)
      unset(__cmake_contentDetails)
      unset(__cmake_arg_SOURCE_SUBDIR)
    endif()
  endforeach()

  # Prefix will be "__fcprefix__"
  list(POP_BACK __cmake_fcCurrentVarsStack __cmake_original_verify_setting)
  string(SUBSTRING "${__cmake_original_verify_setting}"
    12 -1 __cmake_original_verify_setting
  )
  set(CMAKE_VERIFY_INTERFACE_HEADER_SETS ${__cmake_original_verify_setting})

  # clear local variables to prevent leaking into the caller's scope
  unset(__cmake_contentName)
  unset(__cmake_contentNameLower)
  unset(__cmake_contentNameUpper)
  unset(__cmake_providerCommand)
  unset(__cmake_original_verify_setting)

endmacro()
