# 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
  prevents the update step from making connections to remote servers
  when using the git or hg download methods.  Updates still occur if details
  about the update step change, but the update is attempted with only the
  information already available locally (so switching to a different tag or
  commit that is already fetched locally will succeed, but switching to an
  unknown commit hash will fail).  The download step is not affected, so if
  content has not been downloaded previously, it will still be downloaded
  when this option is enabled.  This can speed up the configure step, but
  not as much as :variable:`FETCHCONTENT_FULLY_DISCONNECTED`.
  ``FETCHCONTENT_UPDATES_DISCONNECTED`` 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 for the git and hg methods will not
  contact any remote for the named content.  They will only use information
  already available locally.  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
  set(sep EXTERNALPROJECT_INTERNAL_ARGUMENT_SEPARATOR)
  foreach(key IN LISTS oneValueArgs)
    if(DEFINED ARG_${key})
      list(PREPEND ARG_UNPARSED_ARGUMENTS ${key} "${ARG_${key}}" ${sep})
      set(sep "")
    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()
