| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490 |
- .. cmake-manual-description: CMake Packages Reference
- cmake-packages(7)
- *****************
- .. only:: html or latex
- .. contents::
- Introduction
- ============
- Packages provide dependency information to CMake based buildsystems. Packages
- are found with the :command:`find_package` command. The result of
- using ``find_package`` is either a set of :prop_tgt:`IMPORTED` targets, or
- a set of variables corresponding to build-relevant information.
- Using Packages
- ==============
- CMake provides direct support for two forms of packages,
- `Config-file Packages`_ and `Find-module Packages`_.
- Indirect support for ``pkg-config`` packages is also provided via
- the :module:`FindPkgConfig` module. In all cases, the basic form
- of :command:`find_package` calls is the same:
- .. code-block:: cmake
- find_package(Qt4 4.7.0 REQUIRED) # CMake provides a Qt4 find-module
- find_package(Qt5Core 5.1.0 REQUIRED) # Qt provides a Qt5 package config file.
- find_package(LibXml2 REQUIRED) # Use pkg-config via the LibXml2 find-module
- In cases where it is known that a package configuration file is provided by
- upstream, and only that should be used, the ``CONFIG`` keyword may be passed
- to :command:`find_package`:
- .. code-block:: cmake
- find_package(Qt5Core 5.1.0 CONFIG REQUIRED)
- find_package(Qt5Gui 5.1.0 CONFIG)
- Similarly, the ``MODULE`` keyword says to use only a find-module:
- .. code-block:: cmake
- find_package(Qt4 4.7.0 MODULE REQUIRED)
- Specifying the type of package explicitly improves the error message shown to
- the user if it is not found.
- Both types of packages also support specifying components of a package,
- either after the ``REQUIRED`` keyword:
- .. code-block:: cmake
- find_package(Qt5 5.1.0 CONFIG REQUIRED Widgets Xml Sql)
- or as a separate ``COMPONENTS`` list:
- .. code-block:: cmake
- find_package(Qt5 5.1.0 COMPONENTS Widgets Xml Sql)
- or as a separate ``OPTIONAL_COMPONENTS`` list:
- .. code-block:: cmake
- find_package(Qt5 5.1.0 COMPONENTS Widgets
- OPTIONAL_COMPONENTS Xml Sql
- )
- Handling of ``COMPONENTS`` and ``OPTIONAL_COMPONENTS`` is defined by the
- package.
- By setting the :variable:`CMAKE_DISABLE_FIND_PACKAGE_<PackageName>` variable to
- ``TRUE``, the ``PackageName`` package will not be searched, and will always
- be ``NOTFOUND``.
- Config-file Packages
- --------------------
- A config-file package is a set of files provided by upstreams for downstreams
- to use. CMake searches in a number of locations for package configuration files, as
- described in the :command:`find_package` documentation. The most simple way for
- a CMake user to tell :manual:`cmake(1)` to search in a non-standard prefix for
- a package is to set the ``CMAKE_PREFIX_PATH`` cache variable.
- Config-file packages are provided by upstream vendors as part of development
- packages, that is, they belong with the header files and any other files
- provided to assist downsteams in using the package.
- A set of variables which provide package status information are also set
- automatically when using a config-file package. The ``<Package>_FOUND``
- variable is set to true or false, depending on whether the package was
- found. The ``<Package>_DIR`` cache variable is set to the location of the
- package configuration file.
- Find-module Packages
- --------------------
- A find module is a file with a set of rules for finding the required pieces of
- a dependency, primarily header files and libraries. Typically, a find module
- is needed when the upstream is not built with CMake, or is not CMake-aware
- enough to otherwise provide a package configuration file. Unlike a package configuration
- file, it is not shipped with upstream, but is used by downstream to find the
- files by guessing locations of files with platform-specific hints.
- Unlike the case of an upstream-provided package configuration file, no single point
- of reference identifies the package as being found, so the ``<Package>_FOUND``
- variable is not automatically set by the :command:`find_package` command. It
- can still be expected to be set by convention however and should be set by
- the author of the Find-module. Similarly there is no ``<Package>_DIR`` variable,
- but each of the artifacts such as library locations and header file locations
- provide a separate cache variable.
- See the :manual:`cmake-developer(7)` manual for more information about creating
- Find-module files.
- Package Layout
- ==============
- A config-file package consists of a `Package Configuration File`_ and
- optionally a `Package Version File`_ provided with the project distribution.
- Package Configuration File
- --------------------------
- Consider a project ``Foo`` that installs the following files::
- <prefix>/include/foo-1.2/foo.h
- <prefix>/lib/foo-1.2/libfoo.a
- It may also provide a CMake package configuration file::
- <prefix>/lib/cmake/foo-1.2/FooConfig.cmake
- with content defining :prop_tgt:`IMPORTED` targets, or defining variables, such
- as:
- .. code-block:: cmake
- # ...
- # (compute PREFIX relative to file location)
- # ...
- set(Foo_INCLUDE_DIRS ${PREFIX}/include/foo-1.2)
- set(Foo_LIBRARIES ${PREFIX}/lib/foo-1.2/libfoo.a)
- If another project wishes to use ``Foo`` it need only to locate the ``FooConfig.cmake``
- file and load it to get all the information it needs about package content
- locations. Since the package configuration file is provided by the package
- installation it already knows all the file locations.
- The :command:`find_package` command may be used to search for the package
- configuration file. This command constructs a set of installation prefixes
- and searches under each prefix in several locations. Given the name ``Foo``,
- it looks for a file called ``FooConfig.cmake`` or ``foo-config.cmake``.
- The full set of locations is specified in the :command:`find_package` command
- documentation. One place it looks is::
- <prefix>/lib/cmake/Foo*/
- where ``Foo*`` is a case-insensitive globbing expression. In our example the
- globbing expression will match ``<prefix>/lib/cmake/foo-1.2`` and the package
- configuration file will be found.
- Once found, a package configuration file is immediately loaded. It, together
- with a package version file, contains all the information the project needs to
- use the package.
- Package Version File
- --------------------
- When the :command:`find_package` command finds a candidate package configuration
- file it looks next to it for a version file. The version file is loaded to test
- whether the package version is an acceptable match for the version requested.
- If the version file claims compatibility the configuration file is accepted.
- Otherwise it is ignored.
- The name of the package version file must match that of the package configuration
- file but has either ``-version`` or ``Version`` appended to the name before
- the ``.cmake`` extension. For example, the files::
- <prefix>/lib/cmake/foo-1.3/foo-config.cmake
- <prefix>/lib/cmake/foo-1.3/foo-config-version.cmake
- and::
- <prefix>/lib/cmake/bar-4.2/BarConfig.cmake
- <prefix>/lib/cmake/bar-4.2/BarConfigVersion.cmake
- are each pairs of package configuration files and corresponding package version
- files.
- When the :command:`find_package` command loads a version file it first sets the
- following variables:
- ``PACKAGE_FIND_NAME``
- The <package> name
- ``PACKAGE_FIND_VERSION``
- Full requested version string
- ``PACKAGE_FIND_VERSION_MAJOR``
- Major version if requested, else 0
- ``PACKAGE_FIND_VERSION_MINOR``
- Minor version if requested, else 0
- ``PACKAGE_FIND_VERSION_PATCH``
- Patch version if requested, else 0
- ``PACKAGE_FIND_VERSION_TWEAK``
- Tweak version if requested, else 0
- ``PACKAGE_FIND_VERSION_COUNT``
- Number of version components, 0 to 4
- The version file must use these variables to check whether it is compatible or
- an exact match for the requested version and set the following variables with
- results:
- ``PACKAGE_VERSION``
- Full provided version string
- ``PACKAGE_VERSION_EXACT``
- True if version is exact match
- ``PACKAGE_VERSION_COMPATIBLE``
- True if version is compatible
- ``PACKAGE_VERSION_UNSUITABLE``
- True if unsuitable as any version
- Version files are loaded in a nested scope so they are free to set any variables
- they wish as part of their computation. The find_package command wipes out the
- scope when the version file has completed and it has checked the output
- variables. When the version file claims to be an acceptable match for the
- requested version the find_package command sets the following variables for
- use by the project:
- ``<package>_VERSION``
- Full provided version string
- ``<package>_VERSION_MAJOR``
- Major version if provided, else 0
- ``<package>_VERSION_MINOR``
- Minor version if provided, else 0
- ``<package>_VERSION_PATCH``
- Patch version if provided, else 0
- ``<package>_VERSION_TWEAK``
- Tweak version if provided, else 0
- ``<package>_VERSION_COUNT``
- Number of version components, 0 to 4
- The variables report the version of the package that was actually found.
- The ``<package>`` part of their name matches the argument given to the
- :command:`find_package` command.
- Creating Packages
- =================
- Usually, the upstream depends on CMake itself and can use some CMake facilities
- for creating the package files. Consider an upstream which provides a single
- shared library:
- .. code-block:: cmake
- project(UpstreamLib)
- set(CMAKE_INCLUDE_CURRENT_DIR ON)
- set(CMAKE_INCLUDE_CURRENT_DIR_IN_INTERFACE ON)
- set(Upstream_VERSION 3.4.1)
- include(GenerateExportHeader)
- add_library(ClimbingStats SHARED climbingstats.cpp)
- generate_export_header(ClimbingStats)
- set_property(TARGET ClimbingStats PROPERTY VERSION ${Upstream_VERSION})
- set_property(TARGET ClimbingStats PROPERTY SOVERSION 3)
- set_property(TARGET ClimbingStats PROPERTY INTERFACE_ClimbingStats_MAJOR_VERSION 3)
- set_property(TARGET ClimbingStats APPEND PROPERTY
- COMPATIBLE_INTERFACE_STRING ClimbingStats_MAJOR_VERSION
- )
- install(TARGETS ClimbingStats EXPORT ClimbingStatsTargets
- LIBRARY DESTINATION lib
- ARCHIVE DESTINATION lib
- RUNTIME DESTINATION bin
- INCLUDES DESTINATION include
- )
- install(
- FILES
- climbingstats.h
- "${CMAKE_CURRENT_BINARY_DIR}/climbingstats_export.h"
- DESTINATION
- include
- COMPONENT
- Devel
- )
- include(CMakePackageConfigHelpers)
- write_basic_package_version_file(
- "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfigVersion.cmake"
- VERSION ${Upstream_VERSION}
- COMPATIBILITY AnyNewerVersion
- )
- export(EXPORT ClimbingStatsTargets
- FILE "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsTargets.cmake"
- NAMESPACE Upstream::
- )
- configure_file(cmake/ClimbingStatsConfig.cmake
- "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfig.cmake"
- COPY_ONLY
- )
- set(ConfigPackageLocation lib/cmake/ClimbingStats)
- install(EXPORT ClimbingStatsTargets
- FILE
- ClimbingStatsTargets.cmake
- NAMESPACE
- Upstream::
- DESTINATION
- ${ConfigPackageLocation}
- )
- install(
- FILES
- cmake/ClimbingStatsConfig.cmake
- "${CMAKE_CURRENT_BINARY_DIR}/ClimbingStats/ClimbingStatsConfigVersion.cmake"
- DESTINATION
- ${ConfigPackageLocation}
- COMPONENT
- Devel
- )
- The :module:`CMakePackageConfigHelpers` module provides a macro for creating
- a simple ``ConfigVersion.cmake`` file. This file sets the version of the
- package. It is read by CMake when :command:`find_package` is called to
- determine the compatibility with the requested version, and to set some
- version-specific variables ``<Package>_VERSION``, ``<Package>_VERSION_MAJOR``,
- ``<Package>_VERSION_MINOR`` etc. The :command:`install(EXPORT)` command is
- used to export the targets in the ``ClimbingStatsTargets`` export-set, defined
- previously by the :command:`install(TARGETS)` command. This command generates
- the ``ClimbingStatsTargets.cmake`` file to contain :prop_tgt:`IMPORTED`
- targets, suitable for use by downsteams and arranges to install it to
- ``lib/cmake/ClimbingStats``. The generated ``ClimbingStatsConfigVersion.cmake``
- and a ``cmake/ClimbingStatsConfig.cmake`` are installed to the same location,
- completing the package.
- The generated :prop_tgt:`IMPORTED` targets have appropriate properties set
- to define their usage requirements, such as
- :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES`,
- :prop_tgt:`INTERFACE_COMPILE_DEFINITIONS` and other relevant built-in
- ``INTERFACE_`` properties. The ``INTERFACE`` variant of user-defined
- properties listed in :prop_tgt:`COMPATIBLE_INTERFACE_STRING` and
- other :ref:`Compatible Interface Properties` are also propagated to the
- generated :prop_tgt:`IMPORTED` targets. In the above case,
- ``ClimbingStats_MAJOR_VERSION`` is defined as a string which must be
- compatible among the dependencies of any depender. By setting this custom
- defined user property in this version and in the next version of
- ``ClimbingStats``, :manual:`cmake(1)` will issue a diagnostic if there is an
- attempt to use version 3 together with version 4. Packages can choose to
- employ such a pattern if different major versions of the package are designed
- to be incompatible.
- A ``NAMESPACE`` with double-colons is specified when exporting the targets
- for installation. This convention of double-colons gives CMake a hint that
- the name is an :prop_tgt:`IMPORTED` target when it is used by downstreams
- with the :command:`target_link_libraries` command. This way, CMake can
- issue a diagnostic if the package providing it has not yet been found.
- In this case, when using :command:`install(TARGETS)` the ``INCLUDES DESTINATION``
- was specified. This causes the ``IMPORTED`` targets to have their
- :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` populated with the ``include``
- directory in the :variable:`CMAKE_INSTALL_PREFIX`. When the ``IMPORTED``
- target is used by downsteam, it automatically consumes the entries from
- that property.
- In this case, the ``ClimbingStatsConfig.cmake`` file could be as simple as:
- .. code-block:: cmake
- include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")
- As this allows downstreams to use the ``IMPORTED`` targets. If any macros
- should be provided by the ``ClimbingStats`` package, they should
- be in a separate file which is installed to the same location as the
- ``ClimbingStatsConfig.cmake`` file, and included from there.
- Packages created by :command:`install(EXPORT)` are designed to be relocatable,
- using paths relative to the location of the package itself. When defining
- the interface of a target for ``EXPORT``, keep in mind that the include
- directories should be specified as relative paths which are relative to the
- :variable:`CMAKE_INSTALL_PREFIX`:
- .. code-block:: cmake
- target_include_directories(tgt INTERFACE
- # Wrong, not relocatable:
- $<INSTALL_INTERFACE:${CMAKE_INSTALL_PREFIX}/include/TgtName>
- )
- target_include_directories(tgt INTERFACE
- # Ok, relocatable:
- $<INSTALL_INTERFACE:include/TgtName>
- )
- The ``$<INSTALL_PREFIX>``
- :manual:`generator expression <cmake-generator-expressions(7)>` may be used as
- a placeholder for the install prefix without resulting in a non-relocatable
- package. This is necessary if complex generator expressions are used:
- .. code-block:: cmake
- target_include_directories(tgt INTERFACE
- # Ok, relocatable:
- $<INSTALL_INTERFACE:$<$<CONFIG:Debug>:$<INSTALL_PREFIX>/include/TgtName>>
- )
- The :command:`export(EXPORT)` command creates an :prop_tgt:`IMPORTED` targets
- definition file which is specific to the build-tree, and is not relocatable.
- This can similiarly be used with a suitable package configuration file and
- package version file to define a package for the build tree which may be used
- without installation. Consumers of the build tree can simply ensure that the
- :variable:`CMAKE_PREFIX_PATH` contains the build directory, or set the
- ``ClimbingStats_DIR`` to ``<build_dir>/ClimbingStats`` in the cache.
- This can also be extended to cover dependencies:
- .. code-block:: cmake
- # ...
- add_library(ClimbingStats SHARED climbingstats.cpp)
- generate_export_header(ClimbingStats)
- find_package(Stats 2.6.4 REQUIRED)
- target_link_libraries(ClimbingStats PUBLIC Stats::Types)
- As the ``Stats::Types`` target is a ``PUBLIC`` dependency of ``ClimbingStats``,
- downsteams must also find the ``Stats`` package and link to the ``Stats::Types``
- library. The ``Stats`` package should be found in the ``ClimbingStatsConfig.cmake``
- file to ensure this. The ``find_dependency`` macro from the
- :module:`CMakeFindDependencyMacro` helps with this by propagating
- whether the package is ``REQUIRED``, or ``QUIET`` etc. All ``REQUIRED``
- dependencies of a package should be found in the ``Config.cmake`` file:
- .. code-block:: cmake
- include(CMakeFindDependencyMacro)
- find_dependency(Stats 2.6.4)
- include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")
- include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsMacros.cmake")
- The ``find_dependency`` macro also sets ``ClimbingStats_FOUND`` to ``False`` if
- the dependency is not found, along with a diagnostic that the ``ClimbingStats``
- package can not be used without the ``Stats`` package.
- If ``COMPONENTS`` are specified when the downstream uses :command:`find_package`,
- they are listed in the ``<Package>_FIND_COMPONENTS`` variable. If a particular
- component is non-optional, then the ``<Package>_FIND_REQUIRED_<comp>`` will
- be true. This can be tested with logic in the package configuration file:
- .. code-block:: cmake
- include(CMakeFindDependencyMacro)
- find_dependency(Stats 2.6.4)
- include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")
- include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsMacros.cmake")
- set(_supported_components Plot Table)
- foreach(_comp ${ClimbingStats_FIND_COMPONENTS})
- if (NOT ";${_supported_components};" MATCHES _comp)
- set(ClimbingStats_FOUND False)
- set(ClimbingStats_NOTFOUND_MESSAGE "Specified unsupported component: ${_comp}")
- endif()
- include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStats${_comp}Targets.cmake")
- endforeach()
- Here, the ``ClimbingStats_NOTFOUND_MESSAGE`` is set to a diagnosis that the package
- could not be found because an invalid component was specified. This message
- variable can be set for any case where the ``_FOUND`` variable is set to ``False``,
- and will be displayed to the user.
|