.. cmake-manual-description: CMake Packages Reference | |
cmake-packages(7) | |
***************** | |
.. only:: html | |
.. contents:: | |
Introduction | |
============ | |
Packages provide dependency information to CMake based buildsystems. Packages | |
are found with the :command:`find_package` command. The result of | |
using :command:`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``. Likewise, setting the | |
:variable:`CMAKE_REQUIRE_FIND_PACKAGE_<PackageName>` to ``TRUE`` will make the | |
package REQUIRED. | |
.. _`Config File Packages`: | |
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 downstreams in using the package. | |
A set of variables which provide package status information are also set | |
automatically when using a config-file package. The ``<PackageName>_FOUND`` | |
variable is set to true or false, depending on whether the package was | |
found. The ``<PackageName>_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 ``<PackageName>_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 ``<PackageName>_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 ``<PackageName>`` | |
``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: | |
``<PackageName>_VERSION`` | |
Full provided version string | |
``<PackageName>_VERSION_MAJOR`` | |
Major version if provided, else 0 | |
``<PackageName>_VERSION_MINOR`` | |
Minor version if provided, else 0 | |
``<PackageName>_VERSION_PATCH`` | |
Patch version if provided, else 0 | |
``<PackageName>_VERSION_TWEAK`` | |
Tweak version if provided, else 0 | |
``<PackageName>_VERSION_COUNT`` | |
Number of version components, 0 to 4 | |
The variables report the version of the package that was actually found. | |
The ``<PackageName>`` part of their name matches the argument given to the | |
:command:`find_package` command. | |
.. _`Creating Packages`: | |
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" | |
COPYONLY | |
) | |
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 ``<PackageName>_VERSION``, ``<PackageName>_VERSION_MAJOR``, | |
``<PackageName>_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 downstreams 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 :ref:`usage requirements <Target 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 downstream, it automatically consumes the entries from | |
that property. | |
Creating a Package Configuration File | |
------------------------------------- | |
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. | |
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``, | |
downstreams 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 ``<PackageName>_FIND_COMPONENTS`` variable. If a particular | |
component is non-optional, then the ``<PackageName>_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(_ClimbingStats_supported_components Plot Table) | |
foreach(_comp ${ClimbingStats_FIND_COMPONENTS}) | |
if (NOT ";${_ClimbingStats_supported_components};" MATCHES ";${_comp};") | |
set(ClimbingStats_FOUND False) | |
set(ClimbingStats_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}") | |
endif() | |
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStats${_comp}Targets.cmake") | |
endforeach() | |
Here, the ``ClimbingStats_NOT_FOUND_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. | |
Creating a Package Configuration File for the Build Tree | |
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | |
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 similarly 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. | |
.. _`Creating Relocatable Packages`: | |
Creating Relocatable Packages | |
----------------------------- | |
A relocatable package must not reference absolute paths of files on | |
the machine where the package is built that will not exist on the | |
machines where the package may be installed. | |
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>> | |
) | |
This also applies to paths referencing external dependencies. | |
It is not advisable to populate any properties which may contain | |
paths, such as :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` and | |
:prop_tgt:`INTERFACE_LINK_LIBRARIES`, with paths relevant to dependencies. | |
For example, this code may not work well for a relocatable package: | |
.. code-block:: cmake | |
target_link_libraries(ClimbingStats INTERFACE | |
${Foo_LIBRARIES} ${Bar_LIBRARIES} | |
) | |
target_include_directories(ClimbingStats INTERFACE | |
"$<INSTALL_INTERFACE:${Foo_INCLUDE_DIRS};${Bar_INCLUDE_DIRS}>" | |
) | |
The referenced variables may contain the absolute paths to libraries | |
and include directories **as found on the machine the package was made on**. | |
This would create a package with hard-coded paths to dependencies and not | |
suitable for relocation. | |
Ideally such dependencies should be used through their own | |
:ref:`IMPORTED targets <Imported Targets>` that have their own | |
:prop_tgt:`IMPORTED_LOCATION` and usage requirement properties | |
such as :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` populated | |
appropriately. Those imported targets may then be used with | |
the :command:`target_link_libraries` command for ``ClimbingStats``: | |
.. code-block:: cmake | |
target_link_libraries(ClimbingStats INTERFACE Foo::Foo Bar::Bar) | |
With this approach the package references its external dependencies | |
only through the names of :ref:`IMPORTED targets <Imported Targets>`. | |
When a consumer uses the installed package, the consumer will run the | |
appropriate :command:`find_package` commands (via the ``find_dependency`` | |
macro described above) to find the dependencies and populate the | |
imported targets with appropriate paths on their own machine. | |
Unfortunately many :manual:`modules <cmake-modules(7)>` shipped with | |
CMake do not yet provide :ref:`IMPORTED targets <Imported Targets>` | |
because their development pre-dated this approach. This may improve | |
incrementally over time. Workarounds to create relocatable packages | |
using such modules include: | |
* When building the package, specify each ``Foo_LIBRARY`` cache | |
entry as just a library name, e.g. ``-DFoo_LIBRARY=foo``. This | |
tells the corresponding find module to populate the ``Foo_LIBRARIES`` | |
with just ``foo`` to ask the linker to search for the library | |
instead of hard-coding a path. | |
* Or, after installing the package content but before creating the | |
package installation binary for redistribution, manually replace | |
the absolute paths with placeholders for substitution by the | |
installation tool when the package is installed. | |
.. _`Package Registry`: | |
Package Registry | |
================ | |
CMake provides two central locations to register packages that have | |
been built or installed anywhere on a system: | |
* `User Package Registry`_ | |
* `System Package Registry`_ | |
The registries are especially useful to help projects find packages in | |
non-standard install locations or directly in their own build trees. | |
A project may populate either the user or system registry (using its own | |
means, see below) to refer to its location. | |
In either case the package should store at the registered location a | |
`Package Configuration File`_ (``<PackageName>Config.cmake``) and optionally a | |
`Package Version File`_ (``<PackageName>ConfigVersion.cmake``). | |
The :command:`find_package` command searches the two package registries | |
as two of the search steps specified in its documentation. If it has | |
sufficient permissions it also removes stale package registry entries | |
that refer to directories that do not exist or do not contain a matching | |
package configuration file. | |
.. _`User Package Registry`: | |
User Package Registry | |
--------------------- | |
The User Package Registry is stored in a per-user location. | |
The :command:`export(PACKAGE)` command may be used to register a project | |
build tree in the user package registry. CMake currently provides no | |
interface to add install trees to the user package registry. Installers | |
must be manually taught to register their packages if desired. | |
On Windows the user package registry is stored in the Windows registry | |
under a key in ``HKEY_CURRENT_USER``. | |
A ``<PackageName>`` may appear under registry key:: | |
HKEY_CURRENT_USER\Software\Kitware\CMake\Packages\<PackageName> | |
as a ``REG_SZ`` value, with arbitrary name, that specifies the directory | |
containing the package configuration file. | |
On UNIX platforms the user package registry is stored in the user home | |
directory under ``~/.cmake/packages``. A ``<PackageName>`` may appear under | |
the directory:: | |
~/.cmake/packages/<PackageName> | |
as a file, with arbitrary name, whose content specifies the directory | |
containing the package configuration file. | |
.. _`System Package Registry`: | |
System Package Registry | |
----------------------- | |
The System Package Registry is stored in a system-wide location. | |
CMake currently provides no interface to add to the system package registry. | |
Installers must be manually taught to register their packages if desired. | |
On Windows the system package registry is stored in the Windows registry | |
under a key in ``HKEY_LOCAL_MACHINE``. A ``<PackageName>`` may appear under | |
registry key:: | |
HKEY_LOCAL_MACHINE\Software\Kitware\CMake\Packages\<PackageName> | |
as a ``REG_SZ`` value, with arbitrary name, that specifies the directory | |
containing the package configuration file. | |
There is no system package registry on non-Windows platforms. | |
.. _`Disabling the Package Registry`: | |
Disabling the Package Registry | |
------------------------------ | |
In some cases using the Package Registries is not desirable. CMake | |
allows one to disable them using the following variables: | |
* The :command:`export(PACKAGE)` command does not populate the user | |
package registry when :policy:`CMP0090` is set to ``NEW`` unless the | |
:variable:`CMAKE_EXPORT_PACKAGE_REGISTRY` variable explicitly enables it. | |
When :policy:`CMP0090` is *not* set to ``NEW`` then | |
:command:`export(PACKAGE)` populates the user package registry unless | |
the :variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` variable explicitly | |
disables it. | |
* :variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY` disables the | |
User Package Registry in all the :command:`find_package` calls when | |
set to ``FALSE``. | |
* Deprecated :variable:`CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY` disables the | |
User Package Registry in all the :command:`find_package` calls when set | |
to ``TRUE``. This variable is ignored when | |
:variable:`CMAKE_FIND_USE_PACKAGE_REGISTRY` has been set. | |
* :variable:`CMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY` disables | |
the System Package Registry in all the :command:`find_package` calls. | |
Package Registry Example | |
------------------------ | |
A simple convention for naming package registry entries is to use content | |
hashes. They are deterministic and unlikely to collide | |
(:command:`export(PACKAGE)` uses this approach). | |
The name of an entry referencing a specific directory is simply the content | |
hash of the directory path itself. | |
If a project arranges for package registry entries to exist, such as:: | |
> reg query HKCU\Software\Kitware\CMake\Packages\MyPackage | |
HKEY_CURRENT_USER\Software\Kitware\CMake\Packages\MyPackage | |
45e7d55f13b87179bb12f907c8de6fc4 REG_SZ c:/Users/Me/Work/lib/cmake/MyPackage | |
7b4a9844f681c80ce93190d4e3185db9 REG_SZ c:/Users/Me/Work/MyPackage-build | |
or:: | |
$ cat ~/.cmake/packages/MyPackage/7d1fb77e07ce59a81bed093bbee945bd | |
/home/me/work/lib/cmake/MyPackage | |
$ cat ~/.cmake/packages/MyPackage/f92c1db873a1937f3100706657c63e07 | |
/home/me/work/MyPackage-build | |
then the ``CMakeLists.txt`` code: | |
.. code-block:: cmake | |
find_package(MyPackage) | |
will search the registered locations for package configuration files | |
(``MyPackageConfig.cmake``). The search order among package registry | |
entries for a single package is unspecified and the entry names | |
(hashes in this example) have no meaning. Registered locations may | |
contain package version files (``MyPackageConfigVersion.cmake``) to | |
tell :command:`find_package` whether a specific location is suitable | |
for the version requested. | |
Package Registry Ownership | |
-------------------------- | |
Package registry entries are individually owned by the project installations | |
that they reference. A package installer is responsible for adding its own | |
entry and the corresponding uninstaller is responsible for removing it. | |
The :command:`export(PACKAGE)` command populates the user package registry | |
with the location of a project build tree. Build trees tend to be deleted by | |
developers and have no "uninstall" event that could trigger removal of their | |
entries. In order to keep the registries clean the :command:`find_package` | |
command automatically removes stale entries it encounters if it has sufficient | |
permissions. CMake provides no interface to remove an entry referencing an | |
existing build tree once :command:`export(PACKAGE)` has been invoked. | |
However, if the project removes its package configuration file from the build | |
tree then the entry referencing the location will be considered stale. |