summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--Help/command/cmake_language.rst3
-rw-r--r--Help/command/find_package.rst6
-rw-r--r--Help/guide/using-dependencies/index.rst559
-rw-r--r--Help/variable/CMAKE_FIND_PACKAGE_REDIRECTS_DIR.rst3
-rw-r--r--Modules/FetchContent.cmake8
5 files changed, 405 insertions, 174 deletions
diff --git a/Help/command/cmake_language.rst b/Help/command/cmake_language.rst
index e49862f..cb8d60b 100644
--- a/Help/command/cmake_language.rst
+++ b/Help/command/cmake_language.rst
@@ -236,6 +236,9 @@ Dependency Providers
.. versionadded:: 3.24
+.. note:: A high-level introduction to this feature can be found in the
+ :ref:`Using Dependencies Guide <dependency_providers_overview>`.
+
.. code-block:: cmake
cmake_language(SET_DEPENDENCY_PROVIDER <command>
diff --git a/Help/command/find_package.rst b/Help/command/find_package.rst
index e85892e..37be3cb 100644
--- a/Help/command/find_package.rst
+++ b/Help/command/find_package.rst
@@ -11,6 +11,12 @@ find_package
.. contents::
+.. note:: The :guide:`Using Dependencies Guide` provides a high-level
+ introduction to this general topic. It provides a broader overview of
+ where the ``find_package()`` command fits into the bigger picture,
+ including its relationship to the :module:`FetchContent` module.
+ The guide is recommended pre-reading before moving on to the details below.
+
Find a package (usually provided by something external to the project),
and load its package-specific details. Calls to this command can also
be intercepted by :ref:`dependency providers <dependency_providers>`.
diff --git a/Help/guide/using-dependencies/index.rst b/Help/guide/using-dependencies/index.rst
index f4d7845..03285b6 100644
--- a/Help/guide/using-dependencies/index.rst
+++ b/Help/guide/using-dependencies/index.rst
@@ -8,193 +8,408 @@ Using Dependencies Guide
Introduction
============
-For developers wishing to use CMake to consume a third
-party binary package, there are multiple possibilities
-regarding how to optimally do so, depending on how
-CMake-aware the third-party library is.
-
-CMake files provided with a software package contain
-instructions for finding each build dependency. Some
-build dependencies are optional in that the build may
-succeed with a different feature set if the dependency
-is missing, and some dependencies are required. CMake
-searches well-known locations for each dependency, and
-the provided software may supply additional hints or
-locations to CMake to find each dependency.
-
-If a required dependency is not found by
-:manual:`cmake(1)`, the cache is populated with an entry
-which contains a ``NOTFOUND`` value. This value can be
-replaced by specifying it on the command line, or in
-the :manual:`ccmake(1)` or :manual:`cmake-gui(1)` tool.
-See the :guide:`User Interaction Guide` for
-more about setting cache entries.
-
-Libraries providing Config-file packages
-========================================
-
-The most convenient way for a third-party to provide library
-binaries for use with CMake is to provide
-:ref:`Config File Packages`. These packages are text files
-shipped with the library which instruct CMake how to use the
-library binaries and associated headers, helper tools and
-CMake macros provided by the library.
-
-The config files can usually be found in a directory whose
-name matches the pattern ``lib/cmake/<PackageName>``, though
-they may be in other locations instead. The
-``<PackageName>`` corresponds to use in CMake code with the
-:command:`find_package` command such as
-``find_package(PackageName REQUIRED)``.
-
-The ``lib/cmake/<PackageName>`` directory will contain a
-file which is either named ``<PackageName>Config.cmake``
-or ``<PackageName>-config.cmake``. This is the entry point
+Projects will frequently depend on other projects, assets, and artifacts.
+CMake provides a number of ways to incorporate such things into the build.
+Projects and users have the flexibility to choose between methods that
+best suit their needs.
+
+The primary methods of bringing dependencies into the build are the
+:command:`find_package` command and the :module:`FetchContent` module.
+The :module:`FindPkgConfig` module is also sometimes used, although it
+lacks some of the integration of the other two and is not discussed any
+further in this guide.
+
+Dependencies can also be made available by a custom
+:ref:`dependency provider <dependency_providers>`.
+This might be a third party package manager, or it might be custom code
+implemented by the developer. Dependency providers co-operate with the
+primary methods mentioned above to extend their flexibility.
+
+.. _prebuilt_find_package:
+
+Using Pre-built Packages With ``find_package()``
+================================================
+
+A package needed by the project may already be built and available at some
+location on the user's system. That package might have also been built by
+CMake, or it could have used a different build system entirely. It might
+even just be a collection of files that didn't need to be built at all.
+CMake provides the :command:`find_package` command for these scenarios.
+It searches well-known locations, along with additional hints and paths
+provided by the project or user. It also supports package components and
+packages being optional. Result variables are provided to allow the project
+to customize its own behavior according to whether the package or specific
+components were found.
+
+In most cases, projects should generally use the :ref:`basic signature`.
+Most of the time, this will involve just the package name, maybe a version
+constraint, and the ``REQUIRED`` keyword if the dependency is not optional.
+A set of package components may also be specified.
+
+.. code-block:: cmake
+ :caption: Examples of ``find_package()`` basic signature
+
+ find_package(Catch2)
+ find_package(GTest REQUIRED)
+ find_package(Boost 1.79 COMPONENTS date_time)
+
+The :command:`find_package` command supports two main methods for carrying
+out the search:
+
+**Config mode**
+ With this method, the command looks for files that are typically provided
+ by the package itself. This is the more reliable method of the two, since
+ the package details should always be in sync with the package.
+
+**Module mode**
+ Not all packages are CMake-aware. Many don't provide the files needed to
+ support config mode. For such cases, a Find module file can be provided
+ separately, either by the project or by CMake. A Find module is typically
+ a heuristic implementation which knows what the package normally provides
+ and how to present that package to the project. Since Find modules are
+ usually distributed separately from the package, they are not as reliable.
+ They are typically maintained separately, and they are likely to follow
+ different release schedules, so they can easily become out-of-date.
+
+Depending on the arguments used, :command:`find_package` may use one or both
+of the above methods. By restricting the options to just the basic signature,
+both config mode and module mode can be used to satisfy the dependency.
+The presence of other options may restrict the call to using only one of the
+two methods, potentially reducing the command's ability to find the dependency.
+See the :command:`find_package` documentation for full details about this
+complex topic.
+
+For both search methods, the user can also set cache variables on the
+:manual:`cmake(1)` command line or in the :manual:`ccmake(1)` or
+:manual:`cmake-gui(1)` UI tools to influence and override where to find
+packages. See the :ref:`User Interaction Guide <Setting Build Variables>`
+for more on how to set cache variables.
+
+.. _Libraries providing Config-file packages:
+
+Config-file packages
+--------------------
+
+The preferred way for a third party to provide executables, libraries,
+headers, and other files for use with CMake is to provide
+:ref:`config files <Config File Packages>`. These are text files shipped
+with the package, which define CMake targets, variables, commands, and so on.
+The config file is an ordinary CMake script, which is read in by the
+:command:`find_package` command.
+
+The config files can usually be found in a directory whose name matches the
+pattern ``lib/cmake/<PackageName>``, although they may be in other locations
+instead (see :ref:`search procedure`). The ``<PackageName>`` is usually the
+first argument to the :command:`find_package` command, and it may even be the
+only argument. Alternative names can also be specified with the ``NAMES``
+option:
+
+.. code-block:: cmake
+ :caption: Providing alternative names when finding a package
+
+ find_package(SomeThing
+ NAMES
+ SameThingOtherName # Another name for the package
+ SomeThing # Also still look for its canonical name
+ )
+
+The config file must be named either ``<PackageName>Config.cmake`` or
+``<LowercasePackageName>-config.cmake`` (the former is used for the remainder
+of this guide, but both are supported). This file is the entry point
to the package for CMake. A separate optional file named
-``<PackageName>ConfigVersion.cmake`` may also exist in the
-directory. This file is used by CMake to determine whether
-the version of the third party package satisfies uses of the
-:command:`find_package` command which specify version
-constraints. It is optional to specify a version when using
-:command:`find_package`, even if a ``ConfigVersion`` file is
-present.
-
-If the ``Config.cmake`` file is found and the
-optionally-specified version is satisfied, then the CMake
-:command:`find_package` command considers the package to be
-found and the entire library package is assumed to be
-complete as designed.
-
-There may be additional files providing CMake macros or
-:ref:`imported targets` for you to use. CMake does not
-enforce any naming convention for these
-files. They are related to the primary ``Config`` file by
-use of the CMake :command:`include` command.
-
-:guide:`Invoking CMake <User Interaction Guide>` with the
-intent of using a package of third party binaries requires
-that cmake :command:`find_package` commands succeed in finding
-the package. If the location of the package is in a directory
-known to CMake, the :command:`find_package` call should
-succeed. The directories known to cmake are platform-specific.
-For example, packages installed on Linux with a standard
-system package manager will be found in the ``/usr`` prefix
-automatically. Packages installed in ``Program Files`` on
-Windows will similarly be found automatically.
-
-Packages which are not found automatically are in locations
-not predictable to CMake such as ``/opt/mylib`` or
-``$HOME/dev/prefix``. This is a normal situation and CMake
-provides several ways for users to specify where to find
-such libraries.
+``<PackageName>ConfigVersion.cmake`` or
+``<LowercasePackageName>-config-version.cmake`` may also exist in the same
+directory. This file is used by CMake to determine whether the version of
+the package satisfies any version constraint included in the call to
+:command:`find_package`. It is optional to specify a version when calling
+:command:`find_package`, even if a ``<PackageName>ConfigVersion.cmake``
+file is present.
+
+If the ``<PackageName>Config.cmake`` file is found and any version constraint
+is satisfied, the :command:`find_package` command considers the package to be
+found, and the entire package is assumed to be complete as designed.
+
+There may be additional files providing CMake commands or
+:ref:`imported targets` for you to use. CMake does not enforce any naming
+convention for these files. They are related to the primary
+``<PackageName>Config.cmake`` file by use of the CMake :command:`include`
+command. The ``<PackageName>Config.cmake`` file would typically include
+these for you, so they won't usually require any additional step other than
+the call to :command:`find_package`.
+
+If the location of the package is in a
+:ref:`directory known to CMake <search procedure>`, the
+:command:`find_package` call should succeed. The directories known to CMake
+are platform-specific. For example, packages installed on Linux with a
+standard system package manager will be found in the ``/usr`` prefix
+automatically. Packages installed in ``Program Files`` on Windows will
+similarly be found automatically.
+
+Packages will not be found automatically without help if they are in
+locations not known to CMake, such as ``/opt/mylib`` or ``$HOME/dev/prefix``.
+This is a normal situation, and CMake provides several ways for users to
+specify where to find such libraries.
The :variable:`CMAKE_PREFIX_PATH` variable may be
:ref:`set when invoking CMake <Setting Build Variables>`.
-It is treated as a list of paths to search for
-:ref:`Config File Packages`. A package installed in
-``/opt/somepackage`` will typically install config files
-such as
+It is treated as a list of base paths in which to search for
+:ref:`config files <Config File Packages>`. A package installed in
+``/opt/somepackage`` will typically install config files such as
``/opt/somepackage/lib/cmake/somePackage/SomePackageConfig.cmake``.
In that case, ``/opt/somepackage`` should be added to
:variable:`CMAKE_PREFIX_PATH`.
-The environment variable ``CMAKE_PREFIX_PATH`` may also be
-populated with prefixes to search for packages. Like the
-``PATH`` environment variable, this is a list and needs to use
-the platform-specific environment variable list item separator
-(``:`` on Unix and ``;`` on Windows).
-
-The :variable:`CMAKE_PREFIX_PATH` variable provides convenience
-in cases where multiple prefixes need to be specified, or when
-multiple different package binaries are available in the same
-prefix. Paths to packages may also be specified by setting
-variables matching ``<PackageName>_DIR``, such as
-``SomePackage_DIR``. Note that this is not a prefix but should
-be a full path to a directory containing a config-style package
-file, such as ``/opt/somepackage/lib/cmake/SomePackage/`` in
-the above example.
-
-Imported Targets from Packages
-==============================
-
-A third-party package which provides config-file packages may
-also provide :ref:`Imported targets`. These will be
-specified in files containing configuration-specific file
-paths relevant to the package, such as debug and release
-versions of libraries.
-
-Often the third-party package documentation will point out the
-names of imported targets available after a successful
-``find_package`` for a library. Those imported target names
-can be used with the :command:`target_link_libraries` command.
-
-A complete example which makes a simple use of a third party
-library might look like:
+The environment variable ``CMAKE_PREFIX_PATH`` may also be populated with
+prefixes to search for packages. Like the ``PATH`` environment variable,
+this is a list, but it needs to use the platform-specific environment variable
+list item separator (``:`` on Unix and ``;`` on Windows).
+
+The :variable:`CMAKE_PREFIX_PATH` variable provides convenience in cases
+where multiple prefixes need to be specified, or when multiple packages
+are available under the same prefix. Paths to packages may also be
+specified by setting variables matching ``<PackageName>_DIR``, such as
+``SomePackage_DIR``. Note that this is not a prefix, but should be a full
+path to a directory containing a config-style package file, such as
+``/opt/somepackage/lib/cmake/SomePackage`` in the above example.
+See the :command:`find_package` documentation for other CMake variables and
+environment variables that can affect the search.
+
+.. _Libraries not Providing Config-file Packages:
+
+Find Module Files
+-----------------
+
+Packages which do not provide config files can still be found with the
+:command:`find_package` command, if a ``FindSomePackage.cmake`` file is
+available. These Find module files are different to config files in that:
+
+#. Find module files should not be provided by the package itself.
+#. The availability of a ``Find<PackageName>.cmake`` file does not indicate
+ the availability of the package, or any particular part of the package.
+#. CMake does not search the locations specified in the
+ :variable:`CMAKE_PREFIX_PATH` variable for ``Find<PackageName>.cmake``
+ files. Instead, CMake searches for such files in the locations given
+ by the :variable:`CMAKE_MODULE_PATH` variable. It is common for users to
+ set the :variable:`CMAKE_MODULE_PATH` when running CMake, and it is common
+ for CMake projects to append to :variable:`CMAKE_MODULE_PATH` to allow use
+ of local Find module files.
+#. CMake ships ``Find<PackageName>.cmake`` files for some
+ :manual:`third party packages <cmake-modules(7)>`. These files are a
+ maintenance burden for CMake, and it is not unusual for these to fall
+ behind the latest releases of the packages they are associated with.
+ In general, new Find modules are not added to CMake any more. Projects
+ should encourage the upstream packages to provide a config file where
+ possible. If that is unsuccessful, the project should provide its own
+ Find module for the package.
+
+See :ref:`Find Modules` for a detailed discussion of how to write a
+Find module file.
+
+.. _Imported Targets from Packages:
+
+Imported Targets
+----------------
+
+Both config files and Find module files can define :ref:`Imported targets`.
+These will typically have names of the form ``SomePrefix::ThingName``.
+Where these are available, the project should prefer to use them instead of
+any CMake variables that may also be provided. Such targets typically carry
+usage requirements and apply things like header search paths, compiler
+definitions, etc. automatically to other targets that link to them (e.g. using
+:command:`target_link_libraries`). This is both more robust and more
+convenient than trying to apply the same things manually using variables.
+Check the documentation for the package or Find module to see what imported
+targets it defines, if any.
+
+Imported targets should also encapsulate any configuration-specific paths.
+This includes the location of binaries (libraries, executables), compiler
+flags, and any other configuration-dependent quantities. Find modules may
+be less reliable in providing these details than config files.
+
+A complete example which finds a third party package and uses a library
+from it might look like the following:
.. code-block:: cmake
- cmake_minimum_required(VERSION 3.10)
- project(MyExeProject VERSION 1.0.0)
-
- find_package(SomePackage REQUIRED)
- add_executable(MyExe main.cpp)
- target_link_libraries(MyExe PRIVATE SomePrefix::LibName)
-
-See :manual:`cmake-buildsystem(7)` for further information
-about developing a CMake buildsystem.
-
-Libraries not Providing Config-file Packages
---------------------------------------------
-
-Third-party libraries which do not provide config-file packages
-can still be found with the :command:`find_package` command, if
-a ``FindSomePackage.cmake`` file is available.
-
-These module-file packages are different to config-file packages
-in that:
-
-#. They should not be provided by the third party, except
- perhaps in the form of documentation
-#. The availability of a ``Find<PackageName>.cmake`` file does
- not indicate the availability of the binaries themselves.
-#. CMake does not search the :variable:`CMAKE_PREFIX_PATH` for
- ``Find<PackageName>.cmake`` files. Instead CMake searches
- for such files in the :variable:`CMAKE_MODULE_PATH`
- variable. It is common for users to set the
- :variable:`CMAKE_MODULE_PATH` when running CMake, and it is
- common for CMake projects to append to
- :variable:`CMAKE_MODULE_PATH` to allow use of local
- module-file packages.
-#. CMake ships ``Find<PackageName>.cmake`` files for some
- :manual:`third party packages <cmake-modules(7)>`
- for convenience in cases where the third party does
- not provide config-file packages directly. These files are
- a maintenance burden for CMake, so new Find modules are
- generally not added to CMake anymore. Third-parties should
- provide config file packages instead of relying on a Find
- module to be provided by CMake.
-
-Module-file packages may also provide :ref:`Imported targets`.
-A complete example which finds such a package might look
-like:
+ cmake_minimum_required(VERSION 3.10)
+ project(MyExeProject VERSION 1.0.0)
+
+ # Make project-provided Find modules available
+ list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
+
+ find_package(SomePackage REQUIRED)
+ add_executable(MyExe main.cpp)
+ target_link_libraries(MyExe PRIVATE SomePrefix::LibName)
+
+Note that the above call to :command:`find_package` could be resolved by
+a config file or a Find module. It uses only the basic arguments supported
+by the :ref:`basic signature`. A ``FindSomePackage.cmake`` file in the
+``${CMAKE_CURRENT_SOURCE_DIR}/cmake`` directory would allow the
+:command:`find_package` command to succeed using module mode, for example.
+If no such module file is present, the system would be searched for a config
+file.
+
+
+Downloading And Building From Source With ``FetchContent``
+==========================================================
+
+Dependencies do not necessarily have to be pre-built in order to use them
+with CMake. They can be built from sources as part of the main project.
+The :module:`FetchContent` module provides functionality to download
+content (typically sources, but can be anything) and add it to the main
+project if the dependency also uses CMake. The dependency's sources will
+be built along with the rest of the project, just as though the sources were
+part of the project's own sources.
+
+The general pattern is that the project should first declare all the
+dependencies it wants to use, then ask for them to be made available.
+The following demonstrates the principle (see :ref:`fetch-content-examples`
+for more):
.. code-block:: cmake
- cmake_minimum_required(VERSION 3.10)
- project(MyExeProject VERSION 1.0.0)
+ 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 de6fe184a9ac1a06895cdd1c9b437f0a0bdf14ad # v2.13.4
+ )
+ FetchContent_MakeAvailable(googletest Catch2)
+
+Various download methods are supported, including downloading and extracting
+archives from a URL (a range of archive formats are supported), and a number
+of repository formats including Git, Subversion, and Mercurial.
+Custom download, update, and patch commands can also be used to support
+arbitrary use cases.
+
+When a dependency is added to the project with :module:`FetchContent`, the
+project links to the dependency's targets just like any other target from the
+project. If the dependency provides namespaced targets of the form
+``SomePrefix::ThingName``, the project should link to those rather than to
+any non-namespaced targets. See the next section for why this is recommended.
+
+Not all dependencies can be brought into the project this way. Some
+dependencies define targets whose names clash with other targets from the
+project or other dependencies. Concrete executable and library targets
+created by :command:`add_executable` and :command:`add_library` are global,
+so each one must be unique across the whole build. If a dependency would
+add a clashing target name, it cannot be brought directly into the build
+with this method.
+
+``FetchContent`` And ``find_package()`` Integration
+===================================================
+
+Some dependencies support being added by either :command:`find_package` or
+:module:`FetchContent`. Such dependencies must ensure they define the same
+namespaced targets in both installed and built-from-source scenarios.
+A consuming project then links to those namespaced targets and can handle
+both scenarios transparently, as long as the project does not use anything
+else that isn't provided by both methods.
+
+The project can indicate it is happy to accept a dependency by either method
+using the ``FIND_PACKAGE_ARGS`` option to :command:`FetchContent_Declare`.
+This allows :command:`FetchContent_MakeAvailable` to try satisfying the
+dependency with a call to :command:`find_package` first, using the arguments
+after the ``FIND_PACKAGE_ARGS`` keyword, if any. If that doesn't find the
+dependency, it is built from source as described previously instead.
- find_package(PNG REQUIRED)
+.. code-block:: cmake
- # Add path to a FindSomePackage.cmake file
- list(APPEND CMAKE_MODULE_PATH "${CMAKE_SOURCE_DIR}/cmake")
- find_package(SomePackage REQUIRED)
+ 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_MakeAvailable(googletest)
+
+ add_executable(ThingUnitTest thing_ut.cpp)
+ target_link_libraries(ThingUnitTest GTest::gtest_main)
+
+The above example calls
+:command:`find_package(googletest NAMES GTest) <find_package>` first.
+CMake provides a :module:`FindGTest` module, so if that finds a GTest package
+installed somewhere, it will make it available, and the dependency will not be
+built from source. If no GTest package is found, it *will* be built from
+source. In either case, the ``GTest::gtest_main`` target is expected to be
+defined, so we link our unit test executable to that target.
+
+High-level control is also available through the
+:variable:`FETCHCONTENT_TRY_FIND_PACKAGE_MODE` variable. This can be set to
+``NEVER`` to disable all redirection to :command:`find_package`. It can be
+set to ``ALWAYS`` to try :command:`find_package` even if ``FIND_PACKAGE_ARGS``
+was not specified (this should be used with caution).
+
+The project might also decide that a particular dependency must be built from
+source. This might be needed if a patched or unreleased version of the
+dependency is required, or to satisfy some policy that requires all
+dependencies to be built from source. The project can enforce this by adding
+the ``OVERRIDE_FIND_PACKAGE`` keyword to :command:`FetchContent_Declare`.
+A call to :command:`find_package` for that dependency will then be redirected
+to :command:`FetchContent_MakeAvailable` instead.
- add_executable(MyExe main.cpp)
- target_link_libraries(MyExe PRIVATE
- PNG::PNG
- SomePrefix::LibName
- )
+.. code-block:: cmake
-The :variable:`<PackageName>_ROOT` variable is also
-searched as a prefix for :command:`find_package` calls using
-module-file packages such as ``FindSomePackage``.
+ include(FetchContent)
+ FetchContent_Declare(
+ Catch2
+ URL https://intranet.mycomp.com/vendored/Catch2_2.13.4_patched.tgz
+ URL_HASH MD5=abc123...
+ OVERRIDE_FIND_PACKAGE
+ )
+
+ # The following is automatically redirected to FetchContent_MakeAvailable(Catch2)
+ find_package(Catch2)
+
+For more advanced use cases, see the
+:variable:`CMAKE_FIND_PACKAGE_REDIRECTS_DIR` variable.
+
+.. _dependency_providers_overview:
+
+Dependency Providers
+====================
+
+The preceding section discussed techniques that projects can use to specify
+their dependencies. Ideally, the project shouldn't really care where a
+dependency comes from, as long as it provides the things it expects (often
+just some imported targets). The project says what it needs and may also
+specify where to get it from, in the absence of any other details, so that it
+can still be built out-of-the-box.
+
+The developer, on the other hand, may be much more interested in controlling
+*how* a dependency is provided to the project. You might want to use a
+particular version of a package that you built themself. You might want
+to use a third party package manager. You might want to redirect some
+requests to a different URL on a system you control for security or
+performance reasons. CMake supports these sort of scenarios through
+:ref:`dependency_providers`.
+
+A dependency provider can be set to intercept :command:`find_package` and
+:command:`FetchContent_MakeAvailable` calls. The provider is given an
+opportunity to satisfy such requests before falling back to the built-in
+implementation if the provider doesn't fulfill it.
+
+Only one dependency provider can be set, and it can only be set at a very
+specific point early in the CMake run.
+The :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES` variable lists CMake files
+that will be read while processing the first :command:`project()` call (and
+only that call). This is the only time a dependency provider may be set.
+At most, one single provider is expected to be used throughout the whole
+project.
+
+For some scenarios, the user wouldn't need to know the details of how the
+dependency provider is set. A third party may provide a file that can be
+added to :variable:`CMAKE_PROJECT_TOP_LEVEL_INCLUDES`, which will set up
+the dependency provider on the user's behalf. This is the recommended
+approach for package managers. The developer can use such a file like so::
+
+ cmake -DCMAKE_PROJECT_TOP_LEVEL_INCLUDES=/path/to/package_manager/setup.cmake ...
+
+For details on how to implement your own custom dependency provider, see the
+:command:`cmake_language(SET_DEPENDENCY_PROVIDER)` command.
diff --git a/Help/variable/CMAKE_FIND_PACKAGE_REDIRECTS_DIR.rst b/Help/variable/CMAKE_FIND_PACKAGE_REDIRECTS_DIR.rst
index fa414e4..5d45fb0 100644
--- a/Help/variable/CMAKE_FIND_PACKAGE_REDIRECTS_DIR.rst
+++ b/Help/variable/CMAKE_FIND_PACKAGE_REDIRECTS_DIR.rst
@@ -15,7 +15,8 @@ when it populates a dependency. This allows subsequent calls to
:command:`find_package` for the same dependency to re-use the populated
contents instead of trying to satisfy the dependency from somewhere external
to the build. Projects may also want to write files into this directory in
-some situations (see :ref:`FetchContent-find_package-integration` for examples).
+some situations (see :ref:`FetchContent-find_package-integration-examples`
+for examples).
The directory that ``CMAKE_FIND_PACKAGE_REDIRECTS_DIR`` points to will always
be erased and recreated empty at the start of every CMake run. Any files
diff --git a/Modules/FetchContent.cmake b/Modules/FetchContent.cmake
index 83aafa8..75a161a 100644
--- a/Modules/FetchContent.cmake
+++ b/Modules/FetchContent.cmake
@@ -11,6 +11,12 @@ FetchContent
.. 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
^^^^^^^^
@@ -720,7 +726,7 @@ frameworks are available to the main build:
# Catch2 will be available to the rest of the build
FetchContent_MakeAvailable(googletest Catch2)
-.. _FetchContent-find_package-integration:
+.. _FetchContent-find_package-integration-examples:
Integrating With find_package()
"""""""""""""""""""""""""""""""