summaryrefslogtreecommitdiffstats
path: root/Help/manual/cmake-packages.7.rst
blob: 3367ba472032d8c07191159600ed9fd851bed487 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
.. 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 ``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`:

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

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

Note that 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 relevnt to dependencies.
That would hard-code into installed packages the include directory or library
paths for dependencies **as found on the machine the package was made on**.

That is, code like this is incorrect for targets which will be used to
generate config file packages:

.. code-block:: cmake

  target_link_libraries(ClimbingStats INTERFACE
    ${Boost_LIBRARIES};${OtherDep_LIBRARIES}>
  )
  target_include_directories(ClimbingStats INTERFACE
    $<INSTALL_INTERFACE:${Boost_INCLUDE_DIRS};${OtherDep_INCLUDE_DIRS}>
  )

Dependencies must provide their own :ref:`IMPORTED targets <Imported Targets>`
which have their own :prop_tgt:`INTERFACE_INCLUDE_DIRECTORIES` and
:prop_tgt:`IMPORTED_LOCATION` populated appropriately.  Those
:ref:`IMPORTED targets <Imported Targets>` may then be
used with the :command:`target_link_libraries` command for ``ClimbingStats``.

That way, when a consumer uses the installed package, the
consumer will run the appropriate :command:`find_package` command (via the
find_dependency macro described below) to find
the dependencies on their own machine and populate the
:ref:`IMPORTED targets <Imported Targets>` with appropriate paths. Note that
many modules currently shipped with CMake do not currently provide
:ref:`IMPORTED targets <Imported Targets>`.

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

.. _`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`_ (``<package>Config.cmake``) and optionally a
`Package Version File`_ (``<package>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 ``<package>`` may appear under registry key::

  HKEY_CURRENT_USER\Software\Kitware\CMake\Packages\<package>

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 ``<package>`` may appear under
the directory::

  ~/.cmake/packages/<package>

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 ``<package>`` may appear under
registry key::

  HKEY_LOCAL_MACHINE\Software\Kitware\CMake\Packages\<package>

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 to disable them using the following variables:

 * :variable:`CMAKE_EXPORT_NO_PACKAGE_REGISTRY` disables the
   :command:`export(PACKAGE)` command.
 * :variable:`CMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY` disables the
   User Package Registry in all the :command:`find_package` calls.
 * :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.