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

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

.. only:: html

  .. contents::

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 would normally be defined separately from the
command that performs the actual population.  This separation ensures that
all of the dependency details are defined before anything may try to use those
details 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:

.. code-block:: cmake

  FetchContent_Declare(
    googletest
    GIT_REPOSITORY https://github.com/google/googletest.git
    GIT_TAG        release-1.8.0
  )

For most typical cases, populating the content can then be done with a single
command like so:

.. code-block:: cmake

  FetchContent_MakeAvailable(googletest)

The above command not only populates the content, it also adds it to the main
build (if possible) so that the main build can use the populated project's
targets, etc.  In some cases, the main project may need to have more precise
control over the population or may be required to explicitly define the
population steps (e.g. if CMake versions earlier than 3.14 need to be
supported).  The typical pattern of such custom steps looks like this:

.. code-block:: cmake

  FetchContent_GetProperties(googletest)
  if(NOT googletest_POPULATED)
    FetchContent_Populate(googletest)
    add_subdirectory(${googletest_SOURCE_DIR} ${googletest_BINARY_DIR})
  endif()

Regardless of which population method is used, when using the
declare-populate pattern with a hierarchical project arrangement, projects at
higher levels in the hierarchy are able to override the population details of
content specified anywhere lower in the project hierarchy.  The ability to
detect whether content has already been populated ensures that even if
multiple child projects want certain content to be available, the first one
to populate it wins.  The other child project can simply make use of the
already available content instead of repeating the population for itself.
See the :ref:`Examples <fetch-content-examples>` section which demonstrates
this scenario.

The ``FetchContent`` module also supports defining and populating
content in a single call, with no check for whether the content has been
populated elsewhere in the project already.  This is a more low level
operation and would not normally be the way the module is used, but it is
sometimes useful as part of implementing some higher level feature or to
populate some content in CMake's script mode.


Declaring Content Details
^^^^^^^^^^^^^^^^^^^^^^^^^

.. command:: FetchContent_Declare

  .. code-block:: cmake

    FetchContent_Declare(<name> <contentOptions>...)

  The ``FetchContent_Declare()`` function records the options that describe
  how to populate the specified content, but 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 or update/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.  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        release-1.8.0
    )

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

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

Populating The Content
^^^^^^^^^^^^^^^^^^^^^^

For most common scenarios, population means making content available to the
main build according to previously declared details for that dependency.
There are two main patterns for populating content, one based on calling
:command:`FetchContent_GetProperties` and
:command:`FetchContent_Populate` for more precise control and the other on
calling :command:`FetchContent_MakeAvailable` for a simpler, more automated
approach.  The former generally follows this canonical pattern:

.. _`fetch-content-canonical-pattern`:

.. code-block:: cmake

  # Check if population has already been performed
  FetchContent_GetProperties(<name>)
  string(TOLOWER "<name>" lcName)
  if(NOT ${lcName}_POPULATED)
    # Fetch the content using previously declared details
    FetchContent_Populate(<name>)

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

    # Bring the populated content into the build
    add_subdirectory(${${lcName}_SOURCE_DIR} ${${lcName}_BINARY_DIR})
  endif()

The above is such a common pattern that, where no custom steps are needed
between the calls to :command:`FetchContent_Populate` and
:command:`add_subdirectory`, equivalent logic can be obtained by calling
:command:`FetchContent_MakeAvailable` instead (and should be preferred where
it meets the needs of the project).

.. command:: FetchContent_Populate

  .. 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; ``<lcName>_POPULATED``, ``<lcName>_SOURCE_DIR`` and
  ``<lcName>_BINARY_DIR``, where ``<lcName>`` is the lowercased ``<name>``.
  ``<lcName>_POPULATED`` will always be set to ``True`` by the call.
  ``<lcName>_SOURCE_DIR`` is the location where the
  content can be found upon return (it will have already been populated), while
  ``<lcName>_BINARY_DIR`` is a directory intended for use as a corresponding
  build directory.  The main use case for the two directory variables is to
  call :command:`add_subdirectory` immediately after population, i.e.:

  .. 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.

  A number of cache variables influence the behavior of all content population
  performed using details saved from a :command:`FetchContent_Declare` call:

  ``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.

  ``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.

  ``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.

  ``FETCHCONTENT_UPDATES_DISCONNECTED``
    This is a less severe download/update control compared to
    ``FETCHCONTENT_FULLY_DISCONNECTED``.  Instead of bypassing all download and
    update logic, the ``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
    ``FETCHCONTENT_FULLY_DISCONNECTED``.  It is ``OFF`` by default.

  In addition to the above cache variables, the following cache variables are
  also defined for each content name (``<ucName>`` is the uppercased value of
  ``<name>``):

  ``FETCHCONTENT_SOURCE_DIR_<ucName>``
    If this is set, no download or update steps are performed for the specified
    content and the ``<lcName>_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 ``<lcName>_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.

  ``FETCHCONTENT_UPDATES_DISCONNECTED_<ucName>``
    This is the per-content equivalent of
    ``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.


  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 favour 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 ``<lcName>_SOURCE_DIR`` and ``<lcName>_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
  ``<lcName>_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}/<lcName>-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`.

  ``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}/<lcName>-src`` and ``BINARY_DIR`` defaults to
    ``${CMAKE_CURRENT_BINARY_DIR}/<lcName>-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.


.. command:: FetchContent_GetProperties

  When using saved content details, a call to :command:`FetchContent_Populate`
  records information in global properties which can be queried at any time.
  This information includes 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_Populate(name) <FetchContent_Populate>`.  This allows
  the following canonical pattern to be used, 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

    FetchContent_GetProperties(foobar)
    if(NOT foobar_POPULATED)
      FetchContent_Populate(foobar)
      ...
    endif()

  The above pattern allows other parts of the overall project hierarchy to
  re-use the same content and ensure that it is only populated once.


.. command:: FetchContent_MakeAvailable

  .. code-block:: cmake

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

  This command implements the common pattern typically needed for most
  dependencies.  It iterates over each of the named dependencies in turn
  and for each one it loosely follows the same
  :ref:`canonical pattern <fetch-content-canonical-pattern>` as
  presented at the beginning of this section.  One small difference to
  that pattern is that it will only call :command:`add_subdirectory` on the
  populated content if there is a ``CMakeLists.txt`` file in its top level
  source directory.  This 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.


.. _`fetch-content-examples`:

Examples
^^^^^^^^

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        release-1.8.0
  )
  FetchContent_Declare(
    Catch2
    GIT_REPOSITORY https://github.com/catchorg/Catch2.git
    GIT_TAG        v2.5.0
  )

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


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:

*projA*:

.. code-block:: cmake

  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        origin/release/2.3-rc1
  )

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

*projB*:

.. code-block:: cmake

  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)

*projC*:

.. code-block:: cmake

  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.


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 ``cmake`` is run in the build directory.

Lastly, the following 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.

*getFirmware.cmake*:

.. code-block:: 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
  )

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


set(__FetchContent_privateDir "${CMAKE_CURRENT_LIST_DIR}/FetchContent")

#=======================================================================
# 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(propertyName "_FetchContent_${contentNameLower}_savedDetails")
  get_property(alreadyDefined GLOBAL PROPERTY ${propertyName} DEFINED)
  if(NOT alreadyDefined)
    define_property(GLOBAL PROPERTY ${propertyName}
      BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()"
      FULL_DOCS  "Details used by FetchContent_Populate() for ${contentName}"
    )
    set_property(GLOBAL PROPERTY ${propertyName} ${ARGN})
  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)

  set(options "")
  set(oneValueArgs SVN_REPOSITORY)
  set(multiValueArgs "")

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

  unset(srcDirSuffix)
  unset(svnRepoArgs)
  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)
    set(srcDirSuffix "-${urlSHA}")
    set(svnRepoArgs  SVN_REPOSITORY ${ARG_SVN_REPOSITORY})
  endif()

  string(TOLOWER ${contentName} contentNameLower)
  __FetchContent_declareDetails(
    ${contentNameLower}
    SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src${srcDirSuffix}"
    BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build"
    ${svnRepoArgs}
    # List these last so they can override things we set above
    ${ARG_UNPARSED_ARGUMENTS}
  )

endfunction()


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

# Internal use, projects must not call this directly. It is
# intended for use by the FetchContent_Populate() function to
# record when FetchContent_Populate() is called for a particular
# content name.
function(__FetchContent_setPopulated contentName sourceDir binaryDir)

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

  set(propertyName "${prefix}_sourceDir")
  define_property(GLOBAL PROPERTY ${propertyName}
    BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()"
    FULL_DOCS  "Details used by FetchContent_Populate() for ${contentName}"
  )
  set_property(GLOBAL PROPERTY ${propertyName} ${sourceDir})

  set(propertyName "${prefix}_binaryDir")
  define_property(GLOBAL PROPERTY ${propertyName}
    BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()"
    FULL_DOCS  "Details used by FetchContent_Populate() for ${contentName}"
  )
  set_property(GLOBAL PROPERTY ${propertyName} ${binaryDir})

  set(propertyName "${prefix}_populated")
  define_property(GLOBAL PROPERTY ${propertyName}
    BRIEF_DOCS "Internal implementation detail of FetchContent_Populate()"
    FULL_DOCS  "Details used by FetchContent_Populate() for ${contentName}"
  )
  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
  )
  set(oneValueArgs
      SUBBUILD_DIR
      SOURCE_DIR
      BINARY_DIR
      # Prevent the following from being passed through
      CONFIGURE_COMMAND
      BUILD_COMMAND
      INSTALL_COMMAND
      TEST_COMMAND
      # We force both of 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
  )
  set(multiValueArgs "")

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

  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()

  # 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(generatorOpts "-G${CMAKE_GENERATOR}")
    if(CMAKE_GENERATOR_PLATFORM)
      list(APPEND generatorOpts "-A${CMAKE_GENERATOR_PLATFORM}")
    endif()
    if(CMAKE_GENERATOR_TOOLSET)
      list(APPEND generatorOpts "-T${CMAKE_GENERATOR_TOOLSET}")
    endif()

    if(CMAKE_MAKE_PROGRAM)
      list(APPEND generatorOpts "-DCMAKE_MAKE_PROGRAM:FILEPATH=${CMAKE_MAKE_PROGRAM}")
    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(generatorOpts)
  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.
  configure_file("${__FetchContent_privateDir}/CMakeLists.cmake.in"
                 "${ARG_SUBBUILD_DIR}/CMakeLists.txt")
  execute_process(
    COMMAND ${CMAKE_COMMAND} ${generatorOpts} .
    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 .
    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
    # honours 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)
    message(FATAL_ERROR "Content ${contentName} already populated in ${${contentNameLower}_SOURCE_DIR}")
  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
    set(${contentNameLower}_SOURCE_DIR "${FETCHCONTENT_SOURCE_DIR_${contentNameUpper}}")
    set(${contentNameLower}_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build")

  elseif(FETCHCONTENT_FULLY_DISCONNECTED)
    # Bypass population and assume source is already there from a previous run
    set(${contentNameLower}_SOURCE_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-src")
    set(${contentNameLower}_BINARY_DIR "${FETCHCONTENT_BASE_DIR}/${contentNameLower}-build")

  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()

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

    __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)
      ${contentDetails}
    )
  endif()

  __FetchContent_setPopulated(
    ${contentName}
    ${${contentNameLower}_SOURCE_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()

# 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)

  foreach(contentName IN ITEMS ${ARGV})
    string(TOLOWER ${contentName} contentNameLower)
    FetchContent_GetProperties(${contentName})
    if(NOT ${contentNameLower}_POPULATED)
      FetchContent_Populate(${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.
      if(EXISTS ${${contentNameLower}_SOURCE_DIR}/CMakeLists.txt)
        add_subdirectory(${${contentNameLower}_SOURCE_DIR}
                         ${${contentNameLower}_BINARY_DIR})
      endif()
    endif()
  endforeach()

endmacro()
