CMakePackageConfigHelpers¶
Helper functions for creating config files that can be included by other projects to find and use a package.
Generating a Package Configuration File¶
- configure_package_config_file¶
Create a config file for a project:
configure_package_config_file(<input> <output> INSTALL_DESTINATION <path> [PATH_VARS <var1> <var2> ... <varN>] [NO_SET_AND_CHECK_MACRO] [NO_CHECK_REQUIRED_COMPONENTS_MACRO] [INSTALL_PREFIX <path>] )
configure_package_config_file()
should be used instead of the plain
configure_file()
command when creating the <PackageName>Config.cmake
or <PackageName>-config.cmake
file for installing a project or library.
It helps make the resulting package relocatable by avoiding hardcoded paths
in the installed <PackageName>Config.cmake
file.
In a FooConfig.cmake
file there may be code like this to make the install
destinations known to the using project:
set(FOO_INCLUDE_DIR "@CMAKE_INSTALL_FULL_INCLUDEDIR@" )
set(FOO_DATA_DIR "@CMAKE_INSTALL_PREFIX@/@RELATIVE_DATA_INSTALL_DIR@" )
set(FOO_ICONS_DIR "@CMAKE_INSTALL_PREFIX@/share/icons" )
#...logic to determine installedPrefix from the own location...
set(FOO_CONFIG_DIR "${installedPrefix}/@CONFIG_INSTALL_DIR@" )
All four options shown above are not sufficient The first three hardcode the
absolute directory locations. The fourth case works only if the logic to
determine the installedPrefix
is correct, and if CONFIG_INSTALL_DIR
contains a relative path, which in general cannot be guaranteed. This has the
effect that the resulting FooConfig.cmake
file would work poorly under
Windows and macOS, where users are used to choosing the install location of a
binary package at install time, independent from how
CMAKE_INSTALL_PREFIX
was set at build/cmake time.
Using configure_package_config_file()
helps. If used correctly, it makes
the resulting FooConfig.cmake
file relocatable. Usage:
Write a
FooConfig.cmake.in
file as you are used to.Insert a line at the top containing only the string
@PACKAGE_INIT@
.Instead of
set(FOO_DIR "@SOME_INSTALL_DIR@")
, useset(FOO_DIR "@PACKAGE_SOME_INSTALL_DIR@")
(this must be after the@PACKAGE_INIT@
line).Instead of using the normal
configure_file()
command, useconfigure_package_config_file()
.
The <input>
and <output>
arguments are the input and output file, the
same way as in configure_file()
.
The <path>
given to INSTALL_DESTINATION
must be the destination where
the FooConfig.cmake
file will be installed to. This path can either be
absolute, or relative to the INSTALL_PREFIX
path.
The variables <var1>
to <varN>
given as PATH_VARS
are the
variables which contain install destinations. For each of them, the macro will
create a helper variable PACKAGE_<var...>
. These helper variables must be
used in the FooConfig.cmake.in
file for setting the installed location.
They are calculated by configure_package_config_file()
so that they are
always relative to the installed location of the package. This works both for
relative and also for absolute locations. For absolute locations, it works
only if the absolute location is a subdirectory of INSTALL_PREFIX
.
Added in version 3.30: The variable PACKAGE_PREFIX_DIR
will always be defined after the
@PACKAGE_INIT@
line. It will hold the value of the base install
location. In general, variables defined via the PATH_VARS
mechanism
should be used instead, but PACKAGE_PREFIX_DIR
can be used for those
cases not easily handled by PATH_VARS
, such as for files installed
directly to the base install location rather than a subdirectory of it.
Note
When consumers of the generated file use CMake 3.29 or older, the value
of PACKAGE_PREFIX_DIR
can be changed by a call to
find_dependency()
or find_package()
.
If a project relies on PACKAGE_PREFIX_DIR
, it is the project's
responsibility to ensure that the value of PACKAGE_PREFIX_DIR
is
preserved across any such calls, or any other calls which might include
another file generated by configure_package_config_file()
.
Added in version 3.1: If the INSTALL_PREFIX
argument is passed, this is used as the base path to
calculate all the relative paths. The <path>
argument must be an absolute
path. If this argument is not passed, the CMAKE_INSTALL_PREFIX
variable will be used instead. The default value is good when generating a
FooConfig.cmake
file to use your package from the install tree. When
generating a FooConfig.cmake
file to use your package from the build tree,
this option should be used.
By default, configure_package_config_file()
also generates two helper
macros, set_and_check()
and check_required_components()
, into the
FooConfig.cmake
file.
set_and_check()
should be used instead of the normal set()
command
for setting directories and file locations. In addition to setting the
variable, it also checks that the referenced file or directory actually exists
and fails with a fatal error if it doesn't. This ensures that the generated
FooConfig.cmake
file does not contain wrong references.
Add the NO_SET_AND_CHECK_MACRO
option to prevent the generation of the
set_and_check()
macro in the FooConfig.cmake
file.
check_required_components(<PackageName>)
should be called at the end of
the FooConfig.cmake
file. This macro checks whether all requested,
non-optional components have been found, and if this is not the case, it sets
the Foo_FOUND
variable to FALSE
so that the package is considered to
be not found. It does that by testing the Foo_<Component>_FOUND
variables for all requested required components. This macro should be
called even if the package doesn't provide any components to make sure
users are not specifying components erroneously. Add the
NO_CHECK_REQUIRED_COMPONENTS_MACRO
option to prevent the generation of the
check_required_components()
macro in the FooConfig.cmake
file.
See also Example Generating Package Files.
Generating a Package Version File¶
- write_basic_package_version_file¶
Create a version file for a project:
write_basic_package_version_file(<filename> [VERSION <major.minor.patch>] COMPATIBILITY <AnyNewerVersion|SameMajorVersion|SameMinorVersion|ExactVersion> [ARCH_INDEPENDENT] )
Writes a file for use as a <PackageName>ConfigVersion.cmake
file to
<filename>
. See the documentation of find_package()
for
details on such files.
<filename>
is the output filename, which should be in the build tree.
<major.minor.patch>
is the version number of the project to be installed.
If no VERSION
is given, the PROJECT_VERSION
variable is used.
If this hasn't been set, it errors out.
The COMPATIBILITY
mode AnyNewerVersion
means that the installed
package version will be considered compatible if it is newer or exactly the
same as the requested version. This mode should be used for packages which
are fully backward compatible, also across major versions.
If SameMajorVersion
is used instead, then the behavior differs from
AnyNewerVersion
in that the major version number must be the same as
requested, e.g. version 2.0 will not be considered compatible if 1.0 is
requested. This mode should be used for packages which guarantee backward
compatibility within the same major version.
If SameMinorVersion
is used, the behavior is the same as
SameMajorVersion
, but both major and minor version must be the same as
requested, e.g version 0.2 will not be compatible if 0.1 is requested.
If ExactVersion
is used, then the package is only considered compatible if
the requested version matches exactly its own version number (not considering
the tweak version). For example, version 1.2.3 of a package is only
considered compatible to requested version 1.2.3. This mode is for packages
without compatibility guarantees.
If your project has more elaborate version matching rules, you will need to
write your own custom <PackageName>ConfigVersion.cmake
file instead of
using this macro.
Added in version 3.11: The SameMinorVersion
compatibility mode.
Added in version 3.14: If ARCH_INDEPENDENT
is given, the installed package version will be
considered compatible even if it was built for a different architecture than
the requested architecture. Otherwise, an architecture check will be performed,
and the package will be considered compatible only if the architecture matches
exactly. For example, if the package is built for a 32-bit architecture, the
package is only considered compatible if it is used on a 32-bit architecture,
unless ARCH_INDEPENDENT
is given, in which case the package is considered
compatible on any architecture.
Note
ARCH_INDEPENDENT
is intended for header-only libraries or
similar packages with no binaries.
Added in version 3.19: The version file generated by AnyNewerVersion
, SameMajorVersion
and
SameMinorVersion
arguments of COMPATIBILITY
handle the version range,
if one is specified (see find_package()
command for the details).
ExactVersion
mode is incompatible with version ranges and will display an
author warning if one is specified.
Internally, this macro executes configure_file()
to create the
resulting version file. Depending on the COMPATIBILITY
, the corresponding
BasicConfigVersion-<COMPATIBILITY>.cmake.in
file is used.
Please note that these files are internal to CMake and you should not call
configure_file()
on them yourself, but they can be used as a starting
point to create more sophisticated custom <PackageName>ConfigVersion.cmake
files.
Generating an Apple Platform Selection File¶
- generate_apple_platform_selection_file¶
Added in version 3.29.
Create an Apple platform selection file:
generate_apple_platform_selection_file(<filename> INSTALL_DESTINATION <path> [INSTALL_PREFIX <path>] [MACOS_INCLUDE_FILE <file>] [IOS_INCLUDE_FILE <file>] [IOS_SIMULATOR_INCLUDE_FILE <file>] [IOS_CATALYST_INCLUDE_FILE <file>] [TVOS_INCLUDE_FILE <file>] [TVOS_SIMULATOR_INCLUDE_FILE <file>] [WATCHOS_INCLUDE_FILE <file>] [WATCHOS_SIMULATOR_INCLUDE_FILE <file>] [VISIONOS_INCLUDE_FILE <file>] [VISIONOS_SIMULATOR_INCLUDE_FILE <file>] [ERROR_VARIABLE <variable>] )
Write a file that includes an Apple-platform-specific
.cmake
file, e.g., for use as<PackageName>Config.cmake
. This can be used in conjunction with theXCFRAMEWORK_LOCATION
argument ofexport(SETUP)
to export packages in a way that a project built for any Apple platform can use them.INSTALL_DESTINATION <path>
Path to which the generated file will be installed by the caller, e.g., via
install(FILES)
. The path may be either relative to theINSTALL_PREFIX
or absolute.INSTALL_PREFIX <path>
Path prefix to which the package will be installed by the caller. The
<path>
argument must be an absolute path. If this argument is not passed, theCMAKE_INSTALL_PREFIX
variable will be used instead.MACOS_INCLUDE_FILE <file>
File to include if the platform is macOS.
IOS_INCLUDE_FILE <file>
File to include if the platform is iOS.
IOS_SIMULATOR_INCLUDE_FILE <file>
File to include if the platform is iOS Simulator.
IOS_CATALYST_INCLUDE_FILE <file>
Added in version 3.31.
File to include if the platform is iOS Catalyst.
TVOS_INCLUDE_FILE <file>
File to include if the platform is tvOS.
TVOS_SIMULATOR_INCLUDE_FILE <file>
File to include if the platform is tvOS Simulator.
WATCHOS_INCLUDE_FILE <file>
File to include if the platform is watchOS.
WATCHOS_SIMULATOR_INCLUDE_FILE <file>
File to include if the platform is watchOS Simulator.
VISIONOS_INCLUDE_FILE <file>
File to include if the platform is visionOS.
VISIONOS_SIMULATOR_INCLUDE_FILE <file>
File to include if the platform is visionOS Simulator.
ERROR_VARIABLE <variable>
If the consuming project is built for an unsupported platform, set
<variable>
to an error message. The includer may use this information to pretend the package was not found. If this option is not given, the default behavior is to issue a fatal error.
If any of the optional include files is not specified, and the consuming project is built for its corresponding platform, the generated file will consider the platform to be unsupported. The behavior is determined by the
ERROR_VARIABLE
option.
Generating an Apple Architecture Selection File¶
- generate_apple_architecture_selection_file¶
Added in version 3.29.
Create an Apple architecture selection file:
generate_apple_architecture_selection_file(<filename> INSTALL_DESTINATION <path> [INSTALL_PREFIX <path>] [SINGLE_ARCHITECTURES <arch>... SINGLE_ARCHITECTURE_INCLUDE_FILES <file>...] [UNIVERSAL_ARCHITECTURES <arch>... UNIVERSAL_INCLUDE_FILE <file>] [ERROR_VARIABLE <variable>] )
Write a file that includes an Apple-architecture-specific
.cmake
file based onCMAKE_OSX_ARCHITECTURES
, e.g., for inclusion from an Apple-specific<PackageName>Config.cmake
file.INSTALL_DESTINATION <path>
Path to which the generated file will be installed by the caller, e.g., via
install(FILES)
. The path may be either relative to theINSTALL_PREFIX
or absolute.INSTALL_PREFIX <path>
Path prefix to which the package will be installed by the caller. The
<path>
argument must be an absolute path. If this argument is not passed, theCMAKE_INSTALL_PREFIX
variable will be used instead.SINGLE_ARCHITECTURES <arch>...
Architectures provided by entries of
SINGLE_ARCHITECTURE_INCLUDE_FILES
.SINGLE_ARCHITECTURE_INCLUDE_FILES <file>...
Architecture-specific files. One of them will be loaded when
CMAKE_OSX_ARCHITECTURES
contains a single architecture matching the corresponding entry ofSINGLE_ARCHITECTURES
.UNIVERSAL_ARCHITECTURES <arch>...
Architectures provided by the
UNIVERSAL_INCLUDE_FILE
.The list may include
$(ARCHS_STANDARD)
to support consumption using theXcode
generator, but the architectures should always be listed individually too.UNIVERSAL_INCLUDE_FILE <file>
A file to load when
CMAKE_OSX_ARCHITECTURES
contains a (non-strict) subset of theUNIVERSAL_ARCHITECTURES
and does not match any one of theSINGLE_ARCHITECTURES
.ERROR_VARIABLE <variable>
If the consuming project is built for an unsupported architecture, set
<variable>
to an error message. The includer may use this information to pretend the package was not found. If this option is not given, the default behavior is to issue a fatal error.
Example Generating Package Files¶
Example using both the configure_package_config_file()
and
write_basic_package_version_file()
commands:
include(GNUInstallDirs)
set(INCLUDE_INSTALL_DIR ${CMAKE_INSTALL_INCLUDEDIR}/Foo
CACHE PATH "Location of header files" )
set(SYSCONFIG_INSTALL_DIR ${CMAKE_INSTALL_SYSCONFDIR}/foo
CACHE PATH "Location of configuration files" )
#...
include(CMakePackageConfigHelpers)
configure_package_config_file(FooConfig.cmake.in
${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake
INSTALL_DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Foo
PATH_VARS INCLUDE_INSTALL_DIR SYSCONFIG_INSTALL_DIR)
write_basic_package_version_file(
${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
VERSION 1.2.3
COMPATIBILITY SameMajorVersion )
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/FooConfig.cmake
${CMAKE_CURRENT_BINARY_DIR}/FooConfigVersion.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/Foo )
set(FOO_VERSION x.y.z)
...
@PACKAGE_INIT@
...
set_and_check(FOO_INCLUDE_DIR "@PACKAGE_INCLUDE_INSTALL_DIR@")
set_and_check(FOO_SYSCONFIG_DIR "@PACKAGE_SYSCONFIG_INSTALL_DIR@")
check_required_components(Foo)