898 lines
29 KiB
Groff
898 lines
29 KiB
Groff
|
.\" Man page generated from reStructuredText.
|
||
|
.
|
||
|
.TH "CMAKE-PACKAGES" "7" "Aug 20, 2020" "3.18.2" "CMake"
|
||
|
.SH NAME
|
||
|
cmake-packages \- CMake Packages Reference
|
||
|
.
|
||
|
.nr rst2man-indent-level 0
|
||
|
.
|
||
|
.de1 rstReportMargin
|
||
|
\\$1 \\n[an-margin]
|
||
|
level \\n[rst2man-indent-level]
|
||
|
level margin: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||
|
-
|
||
|
\\n[rst2man-indent0]
|
||
|
\\n[rst2man-indent1]
|
||
|
\\n[rst2man-indent2]
|
||
|
..
|
||
|
.de1 INDENT
|
||
|
.\" .rstReportMargin pre:
|
||
|
. RS \\$1
|
||
|
. nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin]
|
||
|
. nr rst2man-indent-level +1
|
||
|
.\" .rstReportMargin post:
|
||
|
..
|
||
|
.de UNINDENT
|
||
|
. RE
|
||
|
.\" indent \\n[an-margin]
|
||
|
.\" old: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||
|
.nr rst2man-indent-level -1
|
||
|
.\" new: \\n[rst2man-indent\\n[rst2man-indent-level]]
|
||
|
.in \\n[rst2man-indent\\n[rst2man-indent-level]]u
|
||
|
..
|
||
|
.SH INTRODUCTION
|
||
|
.sp
|
||
|
Packages provide dependency information to CMake based buildsystems. Packages
|
||
|
are found with the \fBfind_package()\fP command. The result of
|
||
|
using \fBfind_package()\fP is either a set of \fBIMPORTED\fP targets, or
|
||
|
a set of variables corresponding to build\-relevant information.
|
||
|
.SH USING PACKAGES
|
||
|
.sp
|
||
|
CMake provides direct support for two forms of packages,
|
||
|
\fI\%Config\-file Packages\fP and \fI\%Find\-module Packages\fP\&.
|
||
|
Indirect support for \fBpkg\-config\fP packages is also provided via
|
||
|
the \fBFindPkgConfig\fP module. In all cases, the basic form
|
||
|
of \fBfind_package()\fP calls is the same:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
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
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
In cases where it is known that a package configuration file is provided by
|
||
|
upstream, and only that should be used, the \fBCONFIG\fP keyword may be passed
|
||
|
to \fBfind_package()\fP:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
find_package(Qt5Core 5.1.0 CONFIG REQUIRED)
|
||
|
find_package(Qt5Gui 5.1.0 CONFIG)
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
Similarly, the \fBMODULE\fP keyword says to use only a find\-module:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
find_package(Qt4 4.7.0 MODULE REQUIRED)
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
Specifying the type of package explicitly improves the error message shown to
|
||
|
the user if it is not found.
|
||
|
.sp
|
||
|
Both types of packages also support specifying components of a package,
|
||
|
either after the \fBREQUIRED\fP keyword:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
find_package(Qt5 5.1.0 CONFIG REQUIRED Widgets Xml Sql)
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
or as a separate \fBCOMPONENTS\fP list:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
find_package(Qt5 5.1.0 COMPONENTS Widgets Xml Sql)
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
or as a separate \fBOPTIONAL_COMPONENTS\fP list:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
find_package(Qt5 5.1.0 COMPONENTS Widgets
|
||
|
OPTIONAL_COMPONENTS Xml Sql
|
||
|
)
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
Handling of \fBCOMPONENTS\fP and \fBOPTIONAL_COMPONENTS\fP is defined by the
|
||
|
package.
|
||
|
.sp
|
||
|
By setting the \fBCMAKE_DISABLE_FIND_PACKAGE_<PackageName>\fP variable to
|
||
|
\fBTRUE\fP, the \fB<PackageName>\fP package will not be searched, and will always
|
||
|
be \fBNOTFOUND\fP\&.
|
||
|
.SS Config\-file Packages
|
||
|
.sp
|
||
|
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 \fBfind_package()\fP documentation. The most simple way for
|
||
|
a CMake user to tell \fBcmake(1)\fP to search in a non\-standard prefix for
|
||
|
a package is to set the \fBCMAKE_PREFIX_PATH\fP cache variable.
|
||
|
.sp
|
||
|
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.
|
||
|
.sp
|
||
|
A set of variables which provide package status information are also set
|
||
|
automatically when using a config\-file package. The \fB<PackageName>_FOUND\fP
|
||
|
variable is set to true or false, depending on whether the package was
|
||
|
found. The \fB<PackageName>_DIR\fP cache variable is set to the location of the
|
||
|
package configuration file.
|
||
|
.SS Find\-module Packages
|
||
|
.sp
|
||
|
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.
|
||
|
.sp
|
||
|
Unlike the case of an upstream\-provided package configuration file, no single point
|
||
|
of reference identifies the package as being found, so the \fB<PackageName>_FOUND\fP
|
||
|
variable is not automatically set by the \fBfind_package()\fP 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 \fB<PackageName>_DIR\fP variable,
|
||
|
but each of the artifacts such as library locations and header file locations
|
||
|
provide a separate cache variable.
|
||
|
.sp
|
||
|
See the \fBcmake\-developer(7)\fP manual for more information about creating
|
||
|
Find\-module files.
|
||
|
.SH PACKAGE LAYOUT
|
||
|
.sp
|
||
|
A config\-file package consists of a \fI\%Package Configuration File\fP and
|
||
|
optionally a \fI\%Package Version File\fP provided with the project distribution.
|
||
|
.SS Package Configuration File
|
||
|
.sp
|
||
|
Consider a project \fBFoo\fP that installs the following files:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
<prefix>/include/foo\-1.2/foo.h
|
||
|
<prefix>/lib/foo\-1.2/libfoo.a
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
It may also provide a CMake package configuration file:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
<prefix>/lib/cmake/foo\-1.2/FooConfig.cmake
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
with content defining \fBIMPORTED\fP targets, or defining variables, such
|
||
|
as:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
# ...
|
||
|
# (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)
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
If another project wishes to use \fBFoo\fP it need only to locate the \fBFooConfig.cmake\fP
|
||
|
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.
|
||
|
.sp
|
||
|
The \fBfind_package()\fP 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 \fBFoo\fP,
|
||
|
it looks for a file called \fBFooConfig.cmake\fP or \fBfoo\-config.cmake\fP\&.
|
||
|
The full set of locations is specified in the \fBfind_package()\fP command
|
||
|
documentation. One place it looks is:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
<prefix>/lib/cmake/Foo*/
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
where \fBFoo*\fP is a case\-insensitive globbing expression. In our example the
|
||
|
globbing expression will match \fB<prefix>/lib/cmake/foo\-1.2\fP and the package
|
||
|
configuration file will be found.
|
||
|
.sp
|
||
|
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.
|
||
|
.SS Package Version File
|
||
|
.sp
|
||
|
When the \fBfind_package()\fP 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.
|
||
|
.sp
|
||
|
The name of the package version file must match that of the package configuration
|
||
|
file but has either \fB\-version\fP or \fBVersion\fP appended to the name before
|
||
|
the \fB\&.cmake\fP extension. For example, the files:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
<prefix>/lib/cmake/foo\-1.3/foo\-config.cmake
|
||
|
<prefix>/lib/cmake/foo\-1.3/foo\-config\-version.cmake
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
and:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
<prefix>/lib/cmake/bar\-4.2/BarConfig.cmake
|
||
|
<prefix>/lib/cmake/bar\-4.2/BarConfigVersion.cmake
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
are each pairs of package configuration files and corresponding package version
|
||
|
files.
|
||
|
.sp
|
||
|
When the \fBfind_package()\fP command loads a version file it first sets the
|
||
|
following variables:
|
||
|
.INDENT 0.0
|
||
|
.TP
|
||
|
.B \fBPACKAGE_FIND_NAME\fP
|
||
|
The \fB<PackageName>\fP
|
||
|
.TP
|
||
|
.B \fBPACKAGE_FIND_VERSION\fP
|
||
|
Full requested version string
|
||
|
.TP
|
||
|
.B \fBPACKAGE_FIND_VERSION_MAJOR\fP
|
||
|
Major version if requested, else 0
|
||
|
.TP
|
||
|
.B \fBPACKAGE_FIND_VERSION_MINOR\fP
|
||
|
Minor version if requested, else 0
|
||
|
.TP
|
||
|
.B \fBPACKAGE_FIND_VERSION_PATCH\fP
|
||
|
Patch version if requested, else 0
|
||
|
.TP
|
||
|
.B \fBPACKAGE_FIND_VERSION_TWEAK\fP
|
||
|
Tweak version if requested, else 0
|
||
|
.TP
|
||
|
.B \fBPACKAGE_FIND_VERSION_COUNT\fP
|
||
|
Number of version components, 0 to 4
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
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:
|
||
|
.INDENT 0.0
|
||
|
.TP
|
||
|
.B \fBPACKAGE_VERSION\fP
|
||
|
Full provided version string
|
||
|
.TP
|
||
|
.B \fBPACKAGE_VERSION_EXACT\fP
|
||
|
True if version is exact match
|
||
|
.TP
|
||
|
.B \fBPACKAGE_VERSION_COMPATIBLE\fP
|
||
|
True if version is compatible
|
||
|
.TP
|
||
|
.B \fBPACKAGE_VERSION_UNSUITABLE\fP
|
||
|
True if unsuitable as any version
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
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:
|
||
|
.INDENT 0.0
|
||
|
.TP
|
||
|
.B \fB<PackageName>_VERSION\fP
|
||
|
Full provided version string
|
||
|
.TP
|
||
|
.B \fB<PackageName>_VERSION_MAJOR\fP
|
||
|
Major version if provided, else 0
|
||
|
.TP
|
||
|
.B \fB<PackageName>_VERSION_MINOR\fP
|
||
|
Minor version if provided, else 0
|
||
|
.TP
|
||
|
.B \fB<PackageName>_VERSION_PATCH\fP
|
||
|
Patch version if provided, else 0
|
||
|
.TP
|
||
|
.B \fB<PackageName>_VERSION_TWEAK\fP
|
||
|
Tweak version if provided, else 0
|
||
|
.TP
|
||
|
.B \fB<PackageName>_VERSION_COUNT\fP
|
||
|
Number of version components, 0 to 4
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
The variables report the version of the package that was actually found.
|
||
|
The \fB<PackageName>\fP part of their name matches the argument given to the
|
||
|
\fBfind_package()\fP command.
|
||
|
.SH CREATING PACKAGES
|
||
|
.sp
|
||
|
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:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
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
|
||
|
)
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
The \fBCMakePackageConfigHelpers\fP module provides a macro for creating
|
||
|
a simple \fBConfigVersion.cmake\fP file. This file sets the version of the
|
||
|
package. It is read by CMake when \fBfind_package()\fP is called to
|
||
|
determine the compatibility with the requested version, and to set some
|
||
|
version\-specific variables \fB<PackageName>_VERSION\fP, \fB<PackageName>_VERSION_MAJOR\fP,
|
||
|
\fB<PackageName>_VERSION_MINOR\fP etc. The \fBinstall(EXPORT)\fP command is
|
||
|
used to export the targets in the \fBClimbingStatsTargets\fP export\-set, defined
|
||
|
previously by the \fBinstall(TARGETS)\fP command. This command generates
|
||
|
the \fBClimbingStatsTargets.cmake\fP file to contain \fBIMPORTED\fP
|
||
|
targets, suitable for use by downstreams and arranges to install it to
|
||
|
\fBlib/cmake/ClimbingStats\fP\&. The generated \fBClimbingStatsConfigVersion.cmake\fP
|
||
|
and a \fBcmake/ClimbingStatsConfig.cmake\fP are installed to the same location,
|
||
|
completing the package.
|
||
|
.sp
|
||
|
The generated \fBIMPORTED\fP targets have appropriate properties set
|
||
|
to define their usage requirements, such as
|
||
|
\fBINTERFACE_INCLUDE_DIRECTORIES\fP,
|
||
|
\fBINTERFACE_COMPILE_DEFINITIONS\fP and other relevant built\-in
|
||
|
\fBINTERFACE_\fP properties. The \fBINTERFACE\fP variant of user\-defined
|
||
|
properties listed in \fBCOMPATIBLE_INTERFACE_STRING\fP and
|
||
|
other Compatible Interface Properties are also propagated to the
|
||
|
generated \fBIMPORTED\fP targets. In the above case,
|
||
|
\fBClimbingStats_MAJOR_VERSION\fP 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
|
||
|
\fBClimbingStats\fP, \fBcmake(1)\fP 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.
|
||
|
.sp
|
||
|
A \fBNAMESPACE\fP 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 \fBIMPORTED\fP target when it is used by downstreams
|
||
|
with the \fBtarget_link_libraries()\fP command. This way, CMake can
|
||
|
issue a diagnostic if the package providing it has not yet been found.
|
||
|
.sp
|
||
|
In this case, when using \fBinstall(TARGETS)\fP the \fBINCLUDES DESTINATION\fP
|
||
|
was specified. This causes the \fBIMPORTED\fP targets to have their
|
||
|
\fBINTERFACE_INCLUDE_DIRECTORIES\fP populated with the \fBinclude\fP
|
||
|
directory in the \fBCMAKE_INSTALL_PREFIX\fP\&. When the \fBIMPORTED\fP
|
||
|
target is used by downstream, it automatically consumes the entries from
|
||
|
that property.
|
||
|
.SS Creating a Package Configuration File
|
||
|
.sp
|
||
|
In this case, the \fBClimbingStatsConfig.cmake\fP file could be as simple as:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
As this allows downstreams to use the \fBIMPORTED\fP targets. If any macros
|
||
|
should be provided by the \fBClimbingStats\fP package, they should
|
||
|
be in a separate file which is installed to the same location as the
|
||
|
\fBClimbingStatsConfig.cmake\fP file, and included from there.
|
||
|
.sp
|
||
|
This can also be extended to cover dependencies:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
# ...
|
||
|
add_library(ClimbingStats SHARED climbingstats.cpp)
|
||
|
generate_export_header(ClimbingStats)
|
||
|
|
||
|
find_package(Stats 2.6.4 REQUIRED)
|
||
|
target_link_libraries(ClimbingStats PUBLIC Stats::Types)
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
As the \fBStats::Types\fP target is a \fBPUBLIC\fP dependency of \fBClimbingStats\fP,
|
||
|
downstreams must also find the \fBStats\fP package and link to the \fBStats::Types\fP
|
||
|
library. The \fBStats\fP package should be found in the \fBClimbingStatsConfig.cmake\fP
|
||
|
file to ensure this. The \fBfind_dependency\fP macro from the
|
||
|
\fBCMakeFindDependencyMacro\fP helps with this by propagating
|
||
|
whether the package is \fBREQUIRED\fP, or \fBQUIET\fP etc. All \fBREQUIRED\fP
|
||
|
dependencies of a package should be found in the \fBConfig.cmake\fP file:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
include(CMakeFindDependencyMacro)
|
||
|
find_dependency(Stats 2.6.4)
|
||
|
|
||
|
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")
|
||
|
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsMacros.cmake")
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
The \fBfind_dependency\fP macro also sets \fBClimbingStats_FOUND\fP to \fBFalse\fP if
|
||
|
the dependency is not found, along with a diagnostic that the \fBClimbingStats\fP
|
||
|
package can not be used without the \fBStats\fP package.
|
||
|
.sp
|
||
|
If \fBCOMPONENTS\fP are specified when the downstream uses \fBfind_package()\fP,
|
||
|
they are listed in the \fB<PackageName>_FIND_COMPONENTS\fP variable. If a particular
|
||
|
component is non\-optional, then the \fB<PackageName>_FIND_REQUIRED_<comp>\fP will
|
||
|
be true. This can be tested with logic in the package configuration file:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
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_NOT_FOUND_MESSAGE "Unsupported component: ${_comp}")
|
||
|
endif()
|
||
|
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStats${_comp}Targets.cmake")
|
||
|
endforeach()
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
Here, the \fBClimbingStats_NOT_FOUND_MESSAGE\fP 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 \fB_FOUND\fP variable is set to \fBFalse\fP,
|
||
|
and will be displayed to the user.
|
||
|
.SS Creating a Package Configuration File for the Build Tree
|
||
|
.sp
|
||
|
The \fBexport(EXPORT)\fP command creates an \fBIMPORTED\fP 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
|
||
|
\fBCMAKE_PREFIX_PATH\fP contains the build directory, or set the
|
||
|
\fBClimbingStats_DIR\fP to \fB<build_dir>/ClimbingStats\fP in the cache.
|
||
|
.SS Creating Relocatable Packages
|
||
|
.sp
|
||
|
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.
|
||
|
.sp
|
||
|
Packages created by \fBinstall(EXPORT)\fP are designed to be relocatable,
|
||
|
using paths relative to the location of the package itself. When defining
|
||
|
the interface of a target for \fBEXPORT\fP, keep in mind that the include
|
||
|
directories should be specified as relative paths which are relative to the
|
||
|
\fBCMAKE_INSTALL_PREFIX\fP:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
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>
|
||
|
)
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
The \fB$<INSTALL_PREFIX>\fP
|
||
|
\fBgenerator expression\fP 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:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
target_include_directories(tgt INTERFACE
|
||
|
# Ok, relocatable:
|
||
|
$<INSTALL_INTERFACE:$<$<CONFIG:Debug>:$<INSTALL_PREFIX>/include/TgtName>>
|
||
|
)
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
This also applies to paths referencing external dependencies.
|
||
|
It is not advisable to populate any properties which may contain
|
||
|
paths, such as \fBINTERFACE_INCLUDE_DIRECTORIES\fP and
|
||
|
\fBINTERFACE_LINK_LIBRARIES\fP, with paths relevant to dependencies.
|
||
|
For example, this code may not work well for a relocatable package:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
target_link_libraries(ClimbingStats INTERFACE
|
||
|
${Foo_LIBRARIES} ${Bar_LIBRARIES}
|
||
|
)
|
||
|
target_include_directories(ClimbingStats INTERFACE
|
||
|
"$<INSTALL_INTERFACE:${Foo_INCLUDE_DIRS};${Bar_INCLUDE_DIRS}>"
|
||
|
)
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
The referenced variables may contain the absolute paths to libraries
|
||
|
and include directories \fBas found on the machine the package was made on\fP\&.
|
||
|
This would create a package with hard\-coded paths to dependencies and not
|
||
|
suitable for relocation.
|
||
|
.sp
|
||
|
Ideally such dependencies should be used through their own
|
||
|
IMPORTED targets that have their own
|
||
|
\fBIMPORTED_LOCATION\fP and usage requirement properties
|
||
|
such as \fBINTERFACE_INCLUDE_DIRECTORIES\fP populated
|
||
|
appropriately. Those imported targets may then be used with
|
||
|
the \fBtarget_link_libraries()\fP command for \fBClimbingStats\fP:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
target_link_libraries(ClimbingStats INTERFACE Foo::Foo Bar::Bar)
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
With this approach the package references its external dependencies
|
||
|
only through the names of IMPORTED targets\&.
|
||
|
When a consumer uses the installed package, the consumer will run the
|
||
|
appropriate \fBfind_package()\fP commands (via the \fBfind_dependency\fP
|
||
|
macro described above) to find the dependencies and populate the
|
||
|
imported targets with appropriate paths on their own machine.
|
||
|
.sp
|
||
|
Unfortunately many \fBmodules\fP shipped with
|
||
|
CMake do not yet provide IMPORTED targets
|
||
|
because their development pre\-dated this approach. This may improve
|
||
|
incrementally over time. Workarounds to create relocatable packages
|
||
|
using such modules include:
|
||
|
.INDENT 0.0
|
||
|
.IP \(bu 2
|
||
|
When building the package, specify each \fBFoo_LIBRARY\fP cache
|
||
|
entry as just a library name, e.g. \fB\-DFoo_LIBRARY=foo\fP\&. This
|
||
|
tells the corresponding find module to populate the \fBFoo_LIBRARIES\fP
|
||
|
with just \fBfoo\fP to ask the linker to search for the library
|
||
|
instead of hard\-coding a path.
|
||
|
.IP \(bu 2
|
||
|
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.
|
||
|
.UNINDENT
|
||
|
.SH PACKAGE REGISTRY
|
||
|
.sp
|
||
|
CMake provides two central locations to register packages that have
|
||
|
been built or installed anywhere on a system:
|
||
|
.INDENT 0.0
|
||
|
.IP \(bu 2
|
||
|
\fI\%User Package Registry\fP
|
||
|
.IP \(bu 2
|
||
|
\fI\%System Package Registry\fP
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
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
|
||
|
\fI\%Package Configuration File\fP (\fB<PackageName>Config.cmake\fP) and optionally a
|
||
|
\fI\%Package Version File\fP (\fB<PackageName>ConfigVersion.cmake\fP).
|
||
|
.sp
|
||
|
The \fBfind_package()\fP 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.
|
||
|
.SS User Package Registry
|
||
|
.sp
|
||
|
The User Package Registry is stored in a per\-user location.
|
||
|
The \fBexport(PACKAGE)\fP 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.
|
||
|
.sp
|
||
|
On Windows the user package registry is stored in the Windows registry
|
||
|
under a key in \fBHKEY_CURRENT_USER\fP\&.
|
||
|
.sp
|
||
|
A \fB<PackageName>\fP may appear under registry key:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
HKEY_CURRENT_USER\eSoftware\eKitware\eCMake\ePackages\e<PackageName>
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
as a \fBREG_SZ\fP value, with arbitrary name, that specifies the directory
|
||
|
containing the package configuration file.
|
||
|
.sp
|
||
|
On UNIX platforms the user package registry is stored in the user home
|
||
|
directory under \fB~/.cmake/packages\fP\&. A \fB<PackageName>\fP may appear under
|
||
|
the directory:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
~/.cmake/packages/<PackageName>
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
as a file, with arbitrary name, whose content specifies the directory
|
||
|
containing the package configuration file.
|
||
|
.SS System Package Registry
|
||
|
.sp
|
||
|
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.
|
||
|
.sp
|
||
|
On Windows the system package registry is stored in the Windows registry
|
||
|
under a key in \fBHKEY_LOCAL_MACHINE\fP\&. A \fB<PackageName>\fP may appear under
|
||
|
registry key:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
HKEY_LOCAL_MACHINE\eSoftware\eKitware\eCMake\ePackages\e<PackageName>
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
as a \fBREG_SZ\fP value, with arbitrary name, that specifies the directory
|
||
|
containing the package configuration file.
|
||
|
.sp
|
||
|
There is no system package registry on non\-Windows platforms.
|
||
|
.SS Disabling the Package Registry
|
||
|
.sp
|
||
|
In some cases using the Package Registries is not desirable. CMake
|
||
|
allows one to disable them using the following variables:
|
||
|
.INDENT 0.0
|
||
|
.IP \(bu 2
|
||
|
The \fBexport(PACKAGE)\fP command does not populate the user
|
||
|
package registry when \fBCMP0090\fP is set to \fBNEW\fP unless the
|
||
|
\fBCMAKE_EXPORT_PACKAGE_REGISTRY\fP variable explicitly enables it.
|
||
|
When \fBCMP0090\fP is \fInot\fP set to \fBNEW\fP then
|
||
|
\fBexport(PACKAGE)\fP populates the user package registry unless
|
||
|
the \fBCMAKE_EXPORT_NO_PACKAGE_REGISTRY\fP variable explicitly
|
||
|
disables it.
|
||
|
.IP \(bu 2
|
||
|
\fBCMAKE_FIND_USE_PACKAGE_REGISTRY\fP disables the
|
||
|
User Package Registry in all the \fBfind_package()\fP calls when
|
||
|
set to \fBFALSE\fP\&.
|
||
|
.IP \(bu 2
|
||
|
Deprecated \fBCMAKE_FIND_PACKAGE_NO_PACKAGE_REGISTRY\fP disables the
|
||
|
User Package Registry in all the \fBfind_package()\fP calls when set
|
||
|
to \fBTRUE\fP\&. This variable is ignored when
|
||
|
\fBCMAKE_FIND_USE_PACKAGE_REGISTRY\fP has been set.
|
||
|
.IP \(bu 2
|
||
|
\fBCMAKE_FIND_PACKAGE_NO_SYSTEM_PACKAGE_REGISTRY\fP disables
|
||
|
the System Package Registry in all the \fBfind_package()\fP calls.
|
||
|
.UNINDENT
|
||
|
.SS Package Registry Example
|
||
|
.sp
|
||
|
A simple convention for naming package registry entries is to use content
|
||
|
hashes. They are deterministic and unlikely to collide
|
||
|
(\fBexport(PACKAGE)\fP uses this approach).
|
||
|
The name of an entry referencing a specific directory is simply the content
|
||
|
hash of the directory path itself.
|
||
|
.sp
|
||
|
If a project arranges for package registry entries to exist, such as:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
> reg query HKCU\eSoftware\eKitware\eCMake\ePackages\eMyPackage
|
||
|
HKEY_CURRENT_USER\eSoftware\eKitware\eCMake\ePackages\eMyPackage
|
||
|
45e7d55f13b87179bb12f907c8de6fc4 REG_SZ c:/Users/Me/Work/lib/cmake/MyPackage
|
||
|
7b4a9844f681c80ce93190d4e3185db9 REG_SZ c:/Users/Me/Work/MyPackage\-build
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
or:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
$ cat ~/.cmake/packages/MyPackage/7d1fb77e07ce59a81bed093bbee945bd
|
||
|
/home/me/work/lib/cmake/MyPackage
|
||
|
$ cat ~/.cmake/packages/MyPackage/f92c1db873a1937f3100706657c63e07
|
||
|
/home/me/work/MyPackage\-build
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
then the \fBCMakeLists.txt\fP code:
|
||
|
.INDENT 0.0
|
||
|
.INDENT 3.5
|
||
|
.sp
|
||
|
.nf
|
||
|
.ft C
|
||
|
find_package(MyPackage)
|
||
|
.ft P
|
||
|
.fi
|
||
|
.UNINDENT
|
||
|
.UNINDENT
|
||
|
.sp
|
||
|
will search the registered locations for package configuration files
|
||
|
(\fBMyPackageConfig.cmake\fP). 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 (\fBMyPackageConfigVersion.cmake\fP) to
|
||
|
tell \fBfind_package()\fP whether a specific location is suitable
|
||
|
for the version requested.
|
||
|
.SS Package Registry Ownership
|
||
|
.sp
|
||
|
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.
|
||
|
.sp
|
||
|
The \fBexport(PACKAGE)\fP 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 \fBfind_package()\fP
|
||
|
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 \fBexport(PACKAGE)\fP 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.
|
||
|
.SH COPYRIGHT
|
||
|
2000-2020 Kitware, Inc. and Contributors
|
||
|
.\" Generated by docutils manpage writer.
|
||
|
.
|