.
. RS \\$1 . nr rst2man-indent\\n[rst2man-indent-level] \\n[an-margin] . nr rst2man-indent-level +1 .rstReportMargin post:
.. . 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]]
..
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-moduleNINDENT NINDENT 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 find_package(): NDENT 0.0 NDENT 3.5
find_package(Qt5Core 5.1.0 CONFIG REQUIRED) find_package(Qt5Gui 5.1.0 CONFIG)NINDENT NINDENT Similarly, the MODULE keyword says to use only a find-module: NDENT 0.0 NDENT 3.5
find_package(Qt4 4.7.0 MODULE REQUIRED)NINDENT NINDENT 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: NDENT 0.0 NDENT 3.5
find_package(Qt5 5.1.0 CONFIG REQUIRED Widgets Xml Sql)NINDENT NINDENT or as a separate COMPONENTS list: NDENT 0.0 NDENT 3.5
find_package(Qt5 5.1.0 COMPONENTS Widgets Xml Sql)NINDENT NINDENT or as a separate OPTIONAL_COMPONENTS list: NDENT 0.0 NDENT 3.5
find_package(Qt5 5.1.0 COMPONENTS Widgets OPTIONAL_COMPONENTS Xml Sql )NINDENT NINDENT Handling of COMPONENTS and OPTIONAL_COMPONENTS is defined by the package. By setting the CMAKE_DISABLE_FIND_PACKAGE_<PackageName> variable to TRUE, the PackageName package will not be searched, and will always be NOTFOUND.
<prefix>/include/foo-1.2/foo.h <prefix>/lib/foo-1.2/libfoo.aNINDENT NINDENT It may also provide a CMake package configuration file: NDENT 0.0 NDENT 3.5
<prefix>/lib/cmake/foo-1.2/FooConfig.cmakeNINDENT NINDENT with content defining IMPORTED targets, or defining variables, such as: NDENT 0.0 NDENT 3.5
# ... # (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)NINDENT NINDENT 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 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 find_package() command documentation. One place it looks is: NDENT 0.0 NDENT 3.5
<prefix>/lib/cmake/Foo*/NINDENT NINDENT 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.
<prefix>/lib/cmake/foo-1.3/foo-config.cmake <prefix>/lib/cmake/foo-1.3/foo-config-version.cmakeNINDENT NINDENT and: NDENT 0.0 NDENT 3.5
<prefix>/lib/cmake/bar-4.2/BarConfig.cmake <prefix>/lib/cmake/bar-4.2/BarConfigVersion.cmakeNINDENT NINDENT are each pairs of package configuration files and corresponding package version files. When the find_package() command loads a version file it first sets the following variables: NDENT 0.0
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 NINDENT 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: NDENT 0.0
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 NINDENT 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: NDENT 0.0
<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 NINDENT 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.
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 )NINDENT NINDENT The 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 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 install(EXPORT) command is used to export the targets in the ClimbingStatsTargets export-set, defined previously by the install(TARGETS) command. This command generates the ClimbingStatsTargets.cmake file to contain 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 IMPORTED targets have appropriate properties set to define their usage requirements, such as INTERFACE_INCLUDE_DIRECTORIES, INTERFACE_COMPILE_DEFINITIONS and other relevant built-in INTERFACE_ properties. The INTERFACE variant of user-defined properties listed in COMPATIBLE_INTERFACE_STRING and other Compatible Interface Properties are also propagated to the generated 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, 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 IMPORTED target when it is used by downstreams with the 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 install(TARGETS) the INCLUDES DESTINATION was specified. This causes the IMPORTED targets to have their INTERFACE_INCLUDE_DIRECTORIES populated with the include directory in the CMAKE_INSTALL_PREFIX. When the IMPORTED target is used by downsteam, it automatically consumes the entries from that property.
include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake")NINDENT NINDENT 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: NDENT 0.0 NDENT 3.5
# ... add_library(ClimbingStats SHARED climbingstats.cpp) generate_export_header(ClimbingStats) find_package(Stats 2.6.4 REQUIRED) target_link_libraries(ClimbingStats PUBLIC Stats::Types)NINDENT NINDENT 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 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: NDENT 0.0 NDENT 3.5
include(CMakeFindDependencyMacro) find_dependency(Stats 2.6.4) include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsTargets.cmake") include("${CMAKE_CURRENT_LIST_DIR}/ClimbingStatsMacros.cmake")NINDENT NINDENT 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 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: NDENT 0.0 NDENT 3.5
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()NINDENT NINDENT 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.
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> )NINDENT NINDENT The $<INSTALL_PREFIX> generator expression 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: NDENT 0.0 NDENT 3.5
target_include_directories(tgt INTERFACE # Ok, relocatable: $<INSTALL_INTERFACE:$<$<CONFIG:Debug>:$<INSTALL_PREFIX>/include/TgtName>> )NINDENT NINDENT This also applies to paths referencing external dependencies. It is not advisable to populate any properties which may contain paths, such as INTERFACE_INCLUDE_DIRECTORIES and INTERFACE_LINK_LIBRARIES, with paths relevant to dependencies. For example, this code may not work well for a relocatable package: NDENT 0.0 NDENT 3.5
target_link_libraries(ClimbingStats INTERFACE ${Foo_LIBRARIES} ${Bar_LIBRARIES} ) target_include_directories(ClimbingStats INTERFACE "$<INSTALL_INTERFACE:${Foo_INCLUDE_DIRS};${Bar_INCLUDE_DIRS}>" )NINDENT NINDENT 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 IMPORTED targets that have their own IMPORTED_LOCATION and usage requirement properties such as INTERFACE_INCLUDE_DIRECTORIES populated appropriately. Those imported targets may then be used with the target_link_libraries() command for ClimbingStats: NDENT 0.0 NDENT 3.5
target_link_libraries(ClimbingStats INTERFACE Foo::Foo Bar::Bar)NINDENT NINDENT 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 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 modules 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: NDENT 0.0
HKEY_CURRENT_USER\eSoftware\eKitware\eCMake\ePackages\e<package>NINDENT NINDENT 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: NDENT 0.0 NDENT 3.5
~/.cmake/packages/<package>NINDENT NINDENT as a file, with arbitrary name, whose content specifies the directory containing the package configuration file.
HKEY_LOCAL_MACHINE\eSoftware\eKitware\eCMake\ePackages\e<package>NINDENT NINDENT 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.
> 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-buildNINDENT NINDENT or: NDENT 0.0 NDENT 3.5
$ cat ~/.cmake/packages/MyPackage/7d1fb77e07ce59a81bed093bbee945bd /home/me/work/lib/cmake/MyPackage $ cat ~/.cmake/packages/MyPackage/f92c1db873a1937f3100706657c63e07 /home/me/work/MyPackage-buildNINDENT NINDENT then the CMakeLists.txt code: NDENT 0.0 NDENT 3.5
find_package(MyPackage)NINDENT NINDENT 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 find_package() whether a specific location is suitable for the version requested.
.