| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419 | 
							- Using Dependencies Guide
 
- ************************
 
- .. only:: html
 
-    .. contents::
 
- Introduction
 
- ============
 
- 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`` 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 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, 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)
 
-   # 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
 
-   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
 
-   )
 
-   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
 
- ===================================================
 
- .. versionadded:: 3.24
 
- 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.
 
- .. 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_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.
 
- .. code-block:: cmake
 
-   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
 
- ====================
 
- .. versionadded:: 3.24
 
- 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 yourself.  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.
 
 
  |