目录
Summary:
1. find_package的两种搜索模式
1.1 Module Mode
1.2 Config Mode
两种Mode的选择
2 两种Signature
2.1 Basi signature
2.2 full signature
2.3 Config Mode Search Procedure¶
2.4 Config Mode Version Selection
介绍cmake 的find_package指令的概念、用法以及相关周边概念。阅读官方文档(find_package — CMake 3.22.0-rc3 Documentation) 能得到较为全面的理解。本Blog结合官方文档以及遇到的现实case,进行叙述。
In this mode, CMake searches for a file calledFind
, looking first in the locations listed in the.cmake CMAKE_MODULE_PATH
, then among the Find Modules provided by the CMake installation. If the file is found, it is read and processed by CMake. It is responsible for finding the package, checking the version, and producing any needed messages. Some Find modules provide limited or no support for versioning; check the Find module's documentation.The
Find
file is not typically provided by the package itself. Rather, it is normally provided by something external to the package, such as the operating system, CMake itself, or even the project from which the.cmake find_package()
command was called. Being externally provided, Find Modules tend to be heuristic in nature and are susceptible to becoming out-of-date. They typically search for certain libraries, files and other package artifacts.Module mode is only supported by the basic command signature.
在该模式下, CMake会搜索名字为Find
的文件。该文件一般会定义头文件路径、lib路径等。首先在CMAKE_MODULE_PATH
指定的路径下搜索, 然后会在安装CMake时的一些模块路径下搜索。
一般的package中并不会提供Find
文件,一般是由
pgakage
的使用者自己写这个文件
,这种情况下会存在
.cmake
文件和
package
不一致问题,例如
package
突然更新了。
该模式只能对应
baseic command signature.
In this mode, CMake searches for a file called
or
-config.cmake . It will also look for
Config.cmake or
-config-version.cmake if version details were specified (see Config Mode Version Selection for an explanation of how these separate version files are used).
ConfigVersion.cmake In config mode, the command can be given a list of names to search for as package names. The locations where CMake searches for the config and version files is considerably more complicated than for Module mode (see Config Mode Search Procedure).
The config and version files are typically installed as part of the package, so they tend to be more reliable than Find modules. They usually contain direct knowledge of the package contents, so no searching or heuristics are needed within the config or version files themselves.
Config mode is supported by both the basic and full command signatures.
该模式下,CMake会搜索名字为
or 的文件
,如果指定了版本,还需要搜索
文件
。 搜索路径和搜索顺序后面的会单独讲解。
这种文件通常由
package
的发布者提供,很可靠。
该模式可以对应
baseic/
full
command signature.
The command arguments determine which of the above modes is used. When the basic signature is used, the command searches in Module mode first. If the package is not found, the search falls back to Config mode. A user may set theCMAKE_FIND_PACKAGE_PREFER_CONFIG
variable to true to reverse the priority and direct CMake to search using Config mode first before falling back to Module mode. The basic signature can also be forced to use only Module mode with aMODULE
keyword. If the full signature is used, the command only searches in Config mode.Where possible, user code should generally look for packages using the basic signature, since that allows the package to be found with either mode. Project maintainers wishing to provide a config package should understand the bigger picture, as explained in Full Signature and all subsequent sections on this page.
例如,这3种情况下是Config模式:
find_package()中指定CONFIG关键字
find_package()中指定NO_MODULE关键字
find_package()中使用了不属于"basic signature"的关键字
find_package( [version] [EXACT] [QUIET] [MODULE]
[REQUIRED] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...]
[NO_POLICY_SCOPE] )
The basic signature is supported by both Module and Config modes. The MODULE
keyword implies that only Module mode can be used to find the package, with no fallback to Config mode.
Regardless of the mode used, a
variable will be set to indicate whether the package was found.
When the package is found, package-specific information may be provided through other variables and Imported Targets documented by the package itself.
QUIET:
The QUIET
option disables informational messages, including those indicating that the package cannot be found if it is not REQUIRED
.
REQUIRED:
The REQUIRED
option stops processing with an error message if the package cannot be found.
COMPONENTS:
A package-specific list of required components may be listed after the COMPONENTS
keyword. If any of these components are not able to be satisfied, the package overall is considered to be not found. If the REQUIRED
option is also present, this is treated as a fatal error, otherwise execution still continues. As a form of shorthand, if the REQUIRED
option is present, the COMPONENTS
keyword can be omitted and the required components can be listed directly after REQUIRED
.
OPTIONAL_COMPONENTS:
Additional optional components may be listed after OPTIONAL_COMPONENTS
. If these cannot be satisfied, the package overall can still be considered found, as long as all required components are satisfied.
The set of available components and their meaning are defined by the target package. Formally, it is up to the target package how to interpret the component information given to it, but it should follow the expectations stated above. For calls where no components are specified, there is no single expected behavior and target packages should clearly define what occurs in such cases. Common arrangements include assuming it should find all components, no components or some well-defined subset of the available components.
version:
The [version]
argument requests a version with which the package found should be compatible. There are two possible forms in which it may be specified:
A single version with the format
major[.minor[.patch[.tweak]]]
, where each component is a numeric value.A version range with the format
versionMin...[<]versionMax
whereversionMin
andversionMax
have the same format and constraints on components being integers as the single version. By default, both end points are included. By specifying<
, the upper end point will be excluded. Version ranges are only supported with CMake 3.19 or later.
The EXACT
option requests that the version be matched exactly. This option is incompatible with the specification of a version range.
If no [version]
and/or component list is given to a recursive invocation inside a find-module, the corresponding arguments are forwarded automatically from the outer call (including the EXACT
flag for [version]
). Version support is currently provided only on a package-by-package basis (see the Version Selection section below). When a version range is specified but the package is only designed to expect a single version, the package will ignore the upper end point of the range and only take the single version at the lower end of the range into account.
See the cmake_policy() command documentation for discussion of the NO_POLICY_SCOPE
option.
find_package(<PackageName> [version] [EXACT] [QUIET] [REQUIRED] [[COMPONENTS] [components...]] [OPTIONAL_COMPONENTS components...] [CONFIG|NO_MODULE] [NO_POLICY_SCOPE] [NAMES name1 [name2 ...]] [CONFIGS config1 [config2 ...]] [HINTS path1 [path2 ... ]] [PATHS path1 [path2 ... ]] [PATH_SUFFIXES suffix1 [suffix2 ...]] [NO_DEFAULT_PATH] [NO_PACKAGE_ROOT_PATH] [NO_CMAKE_PATH] [NO_CMAKE_ENVIRONMENT_PATH] [NO_SYSTEM_ENVIRONMENT_PATH] [NO_CMAKE_PACKAGE_REGISTRY] [NO_CMAKE_BUILDS_PATH] # Deprecated; does nothing. [NO_CMAKE_SYSTEM_PATH] [NO_CMAKE_SYSTEM_PACKAGE_REGISTRY] [CMAKE_FIND_ROOT_PATH_BOTH | ONLY_CMAKE_FIND_ROOT_PATH | NO_CMAKE_FIND_ROOT_PATH])
The CONFIG
option, the synonymous NO_MODULE
option, or the use of options not specified in the basic signature all enforce pure Config mode. In pure Config mode, the command skips Module mode search and proceeds at once with Config mode search.
Config mode search attempts to locate a configuration file provided by the package to be found. A cache entry called
is created to hold the directory containing the file. By default the command searches for a package with the name
. If the NAMES
option is given the names following it are used instead of
.
The command searches for a file called
or
for each name specified. A replacement set of possible configuration file names may be given using the CONFIGS
option.
The Config Mode Search Procedure is specified below. Once found, any version constraint is checked, and if satisfied, the configuration file is read and processed by CMake. Since the file is provided by the package it already knows the location of package contents. The full path to the configuration file is stored in the cmake variable
.
All configuration files which have been considered by CMake while searching for the package with an appropriate version are stored in the
variable, and the associated versions in the
variable.
If the package configuration file cannot be found CMake will generate an error describing the problem unless the QUIET
argument is specified.
If REQUIRED
is specified and the package is not found a fatal error is generated and the configure step stops executing.
If
has been set to a directory not containing a configuration file CMake will ignore it and search from scratch.
Package maintainers providing CMake package configuration files are encouraged to name and install them such that the Config Mode Search Procedure outlined below will find them without requiring use of additional options.
Note
When Config mode is used, this search procedure is applied regardless of whether the full or basic signature was given.
The set of installation prefixes is constructed using the following steps. If NO_DEFAULT_PATH
is specified all NO_*
options are enabled.
搜索顺序:
1)New in version 3.12: Search paths specified in the
is the package to be found.
The package root variables are maintained as a stack so if called from within a find module, root paths from the parent's find module will also be searched after paths for the current package.
This can be skipped if NO_PACKAGE_ROOT_PATH
is passed or by setting the CMAKE_FIND_USE_PACKAGE_ROOT_PATH to FALSE
. See policy CMP0074.
2)Search paths specified in cmake-specific cache variables. These are intended to be used on the command line with a -DVAR=value
. The values are interpreted as semicolon-separated lists.
This can be skipped if NO_CMAKE_PATH
is passed or by setting the CMAKE_FIND_USE_CMAKE_PATH to FALSE
:
CMAKE_PREFIX_PATH
CMAKE_FRAMEWORK_PATH
CMAKE_APPBUNDLE_PATH
3)Search paths specified in cmake-specific environment variables. These are intended to be set in the user's shell configuration, and therefore use the host's native path separator (;
on Windows and :
on UNIX). This can be skipped if NO_CMAKE_ENVIRONMENT_PATH
is passed or by setting the CMAKE_FIND_USE_CMAKE_ENVIRONMENT_PATH to FALSE
:
CMAKE_PREFIX_PATH
CMAKE_FRAMEWORK_PATH
CMAKE_APPBUNDLE_PATH
4)...
When the [version]
argument is given, Config mode will only find a version of the package that claims compatibility with the requested version (see format specification). If the EXACT
option is given, only a version of the package claiming an exact match of the requested version may be found.
Ref:
find_package()的使用 - penuel - 博客园