|
|
__TOC__
|
|
|
|
|
|
This page documents creation and use of packages that help projects
|
|
|
locate each other. These features are distinct from CPack which is meant
|
|
|
for creating source and binary distributions and installers.
|
|
|
|
|
|
The `find_package` command has been enhanced with features to help find
|
|
|
packages without the use of "find" modules (FindXXX.cmake files).
|
|
|
Projects that are aware of CMake may provide a "package configuration
|
|
|
file" inside their installation trees. Naming the file correctly and
|
|
|
installing it in a suitable location will allow the `find_package`
|
|
|
command to find it easily.
|
|
|
|
|
|
See also the CMake [Package
|
|
|
Registry](CMake/Tutorials/Package_Registry "wikilink") to help
|
|
|
`find_package` find packages in arbitrary locations.
|
|
|
|
|
|
# Package Configuration Files
|
|
|
|
|
|
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/foo-1.2/foo-config.cmake
|
|
|
|
|
|
with content such as
|
|
|
|
|
|
# ...
|
|
|
# (compute PREFIX relative to file location)
|
|
|
# ...
|
|
|
set(foo_INCLUDE_DIRS ${PREFIX}/include/foo-1.2)
|
|
|
set(foo_LIBRARY ${PREFIX}/lib/foo-1.2/libfoo.a)
|
|
|
|
|
|
If another project wishes to use Foo it need only to locate the
|
|
|
`foo-config.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 `find_package` command may be used to search for the configuration
|
|
|
file:
|
|
|
|
|
|
find_package(Foo)
|
|
|
|
|
|
This command (assuming no `FindFoo.cmake` module exists) 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 `find_package` command documentation, but one place
|
|
|
it looks is
|
|
|
|
|
|
<prefix>/lib/Foo*/
|
|
|
|
|
|
where "`Foo*`" is a case-insensitive globbing expression. In our example
|
|
|
the globbing expression will match "<prefix>`/lib/foo-1.2`" and the
|
|
|
configuration file will be found.
|
|
|
|
|
|
**Note:** If your project does not already have a <prefix>`/lib/Foo*/`
|
|
|
directory you may prefer to put the package file in
|
|
|
<prefix>`/lib/cmake/Foo*/` to keep the `lib` directory clean. However,
|
|
|
CMake 2.6.2 and lower do not search there. CMake 2.6.3 and above do.
|
|
|
|
|
|
Once found, a package configuration file is immediately loaded. It
|
|
|
contains all the information the project needs to use the package.
|
|
|
|
|
|
## Packaging and Exporting
|
|
|
|
|
|
Package configuration files may also work in conjunction with [Exporting
|
|
|
and Importing
|
|
|
Targets](CMake/Tutorials/Exporting_and_Importing_Targets "wikilink").
|
|
|
For example, a project might write
|
|
|
|
|
|
add_library(mylib STATIC mylib.c mylib.h)
|
|
|
install(FILES mylib.h DESTINATION include/myproj)
|
|
|
install(TARGETS mylib EXPORT mylib-targets DESTINATION lib/myproj)
|
|
|
install(EXPORT mylib-targets DESTINATION lib/myproj)
|
|
|
install(FILES myproj-config.cmake DESTINATION lib/myproj)
|
|
|
|
|
|
where `myproj-config.cmake` contains something like
|
|
|
|
|
|
get_filename_component(SELF_DIR "${CMAKE_CURRENT_LIST_FILE}" PATH)
|
|
|
include(${SELF_DIR}/mylib-targets.cmake)
|
|
|
get_filename_component(myproj_INCLUDE_DIRS "${SELF_DIR}/../../include/myproj" ABSOLUTE)
|
|
|
|
|
|
After the project is built and installed, an outside project may use it
|
|
|
by writing
|
|
|
|
|
|
find_package(myproj REQUIRED)
|
|
|
include_directories(${myproj_INCLUDE_DIRS})
|
|
|
add_executable(myexe myexe.c)
|
|
|
target_link_libraries(myexe mylib)
|
|
|
|
|
|
# Package Version Files
|
|
|
|
|
|
The `find_package` command offers a version request argument. One might
|
|
|
write
|
|
|
|
|
|
find_package(Foo 1.2)
|
|
|
find_package(Bar 4.2 EXACT)
|
|
|
|
|
|
in order to get a version of package `Foo` that is compatible with
|
|
|
version 1.2 and exactly package `Bar` version 4.2. CMake does not
|
|
|
attempt to define any convention for the compatibility or exactness of
|
|
|
version numbers for a package. It also does not try to map the version
|
|
|
number to a directory or file name. Instead packages must provide
|
|
|
"version" files next to their package configuration files. This allows
|
|
|
maximum flexibility for project authors and package maintainers.
|
|
|
|
|
|
A package version file is placed next to the package configuration file.
|
|
|
Its name matches that of the configuration file but has either
|
|
|
"`-version`" or "`Version`" appended to the name before the "`.cmake`"
|
|
|
extension. For example, the files
|
|
|
|
|
|
<prefix>/lib/foo-1.3/foo-config.cmake
|
|
|
<prefix>/lib/foo-1.3/foo-config-version.cmake
|
|
|
|
|
|
and
|
|
|
|
|
|
<prefix>/lib/bar-4.2/BarConfig.cmake
|
|
|
<prefix>/lib/bar-4.2/BarConfigVersion.cmake
|
|
|
|
|
|
are each pairs of package configuration files and corresponding version
|
|
|
files. When the `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.
|
|
|
|
|
|
When the `find_package` command loads a version file it first sets the
|
|
|
following variables:
|
|
|
|
|
|
<table>
|
|
|
<thead>
|
|
|
<tr class="header">
|
|
|
<th><p>CMake 2.6.2 and Above</p></th>
|
|
|
<th><p>CMake 2.6.0 and 2.6.1</p></th>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
<tbody>
|
|
|
<tr class="odd">
|
|
|
<td><pre><code>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</code></pre></td>
|
|
|
<td><pre><code>PACKAGE_FIND_NAME = the <package> name
|
|
|
PACKAGE_FIND_VERSION = full requested version string
|
|
|
PACKAGE_FIND_VERSION_MAJOR = requested major version, if any
|
|
|
PACKAGE_FIND_VERSION_MINOR = requested minor version, if any
|
|
|
PACKAGE_FIND_VERSION_PATCH = requested patch version, if any</code></pre></td>
|
|
|
</tr>
|
|
|
</tbody>
|
|
|
</table>
|
|
|
|
|
|
The version file must use these variables to check whether it is
|
|
|
compatible or an exact match for the requested version. It sets 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 (CMake >= 2.6.3)
|
|
|
|
|
|
For example, `foo-config-version.cmake` might contain
|
|
|
|
|
|
set(PACKAGE_VERSION 1.3)
|
|
|
if("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 1)
|
|
|
set(PACKAGE_VERSION_COMPATIBLE 1) # compatible with any version 1.x
|
|
|
if("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 3)
|
|
|
set(PACKAGE_VERSION_EXACT 1) # exact match for version 1.3
|
|
|
endif("${PACKAGE_FIND_VERSION_MINOR}" EQUAL 3)
|
|
|
endif("${PACKAGE_FIND_VERSION_MAJOR}" EQUAL 1)
|
|
|
|
|
|
if it is compatible with all "`1.x`" versions of Foo and exactly matches
|
|
|
version "`1.3`". Note that the input variable names all start in
|
|
|
"`PACKAGE_FIND_`" and the output variable names all start in
|
|
|
"`PACKAGE_`". The names are fixed and do not vary with the package name.
|
|
|
|
|
|
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:
|
|
|
|
|
|
<table>
|
|
|
<thead>
|
|
|
<tr class="header">
|
|
|
<th><p>CMake 2.6.2 and Above</p></th>
|
|
|
<th><p>CMake 2.6.0 and 2.6.1</p></th>
|
|
|
</tr>
|
|
|
</thead>
|
|
|
<tbody>
|
|
|
<tr class="odd">
|
|
|
<td><pre><code><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</code></pre></td>
|
|
|
<td><pre><code><package>_VERSION = package version (major[.minor[.patch]])
|
|
|
<package>_VERSION_MAJOR = major from major[.minor[.patch]], if any
|
|
|
<package>_VERSION_MINOR = minor from major[.minor[.patch]], if any
|
|
|
<package>_VERSION_PATCH = patch from major[.minor[.patch]], if any</code></pre></td>
|
|
|
</tr>
|
|
|
</tbody>
|
|
|
</table>
|
|
|
|
|
|
The variables report the version of the package that was actually found.
|
|
|
The "<package>" part of their name matches the argument given to the
|
|
|
`find_package` command.
|
|
|
|
|
|
----
|
|
|
This page was initially populated by conversion from its [original location](https://public.kitware.com/Wiki/CMake/Tutorials/Packaging) in another wiki. |