查找外部项目, 并加载它的设置
find_package( [version] [EXACT] [QUIET] [MODULE]
[REQUIRED] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...]
[NO_POLICY_SCOPE])
执行该命令之后, 可以通过查询混_Found这个变量来确定是否找到的对应的包。QUIET选项的设置可以用来关闭相关消息的输出, 包括非必须包未能找到的消息。REQUIRED选项设置后,当所查找的包未能找到之后会输出一个错误信息并终止处理过程。指定包所需的特定部件的列表可以跟在COMPONENTS之后。额外的可选部件列表可以跟在OPTIONAL_COMPONENTS后面。
[version] 给出了所找包的版本兼容性要求。版本一般的格式是:major[.minor[.patch[.tweak]]]。 其中major是一个大版本,这种版本变化一般伴随着API的修改之类的变化,可能会存在一些兼容性问题;minor一般是指API增加一类的修改;path通常指的是功能实现、函数实现方式的修改之类的。选项EXACT 指明了版本必须精确匹配。
这个命令用来搜索包有两个模式:模块模式(Module)和配置模式(Config)。默认模式是模块模式,如果在模块模式下没有找到包,则该命令会自动切换到配置模式下进行包的搜索, 可以通过设置标志CMAKE_FIND_PACKAGE_PREFER_CONFIG来确定优先使用Config模式。如果指定了搜索模式,则不会发生这种自动切换模式的搜索策略。在Module模式下,CMake会去搜索一个名为Find.cmake的文件。这个文件会先在CMAKE_MODULE_PATH下搜索, 然后再在CMake安装路径下的Find Module下搜索。如果找到了对应的文件,它会被读取并进行处理。 处理过程中包括查找相应的文件、核验版本和生成所需的信息。
find_package( [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])
通常来说, 第一部分中的简化版的命令接口用来查找包就可以满足大部分实际项目需求。
当在Config模式下指定了[version]参数的时候, 只会寻找与给定版本需求相兼容的包。如果EXACT选项给出了,则表明只查找确定版本的包, 而不是兼容包。CMake没有建立版本号的协议,包的版本号校验需要利用包中的版本文件来进行校验。对于一个候选包的配置文件.cmake, 对应的版本文件存在与之同样的位置,名字通常为-version.cmake 或者Version.cmake。 如果没有这样的版本文件,则认为该包不与任何版本兼容。一个基本的版本文件可以使用CMakePackageConfigHelpers模块来进行生成。当一个版本文件被找到之后,则会被加载以用来进行版本校验。版本文件被加载进入一个内嵌的作用域内,其内定义了一些变量。
变量 | 描述 |
---|---|
PACKAGE_FIND_NAME | PackageName |
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 |
版本文件经过核验之后,如果满足了相应的版本要求则会设置以下几个变量。
变量 | 描述 |
---|---|
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 |
以下几个变量会被find_package命令进行校验,并决定配置文件是否提供了一个可以接受的版本。如果包满足需求,则以下几个变量会被设置且配置文件会被加载。当多个包的配置文件是可用且未指明具体那个包被选择的时候:除非设置了变量CMAKE_FIND_PACKAGE_SORT_ORDER, 则会选择一个最高或者最相近的版本。
变量 | 描述 |
---|---|
_VERSION | full requested version string |
_VERSION_MAJOR | major version if requested, else 0 |
_VERSION_MINOR | minor version if requested, else 0 |
_VERSION_PATCH | patch version if requested, else 0 |
_VERSION_TWEAK | tweak version if requested, else 0 |
_VERSION_COUNT | number of version components, 0 to 4 |
为了控制find_package命令校验包的兼容性顺序,会用到两个变量:CMAKE_FIND_PACKAGE_SORT_ORDER 和 CMAKE_FIND_PACKAGE_SORT_DIRECTION。例如,如果需要选定最高版本的兼容包,可以在使用find_package命令之前这样设置:
SET(CMAKE_FIND_PACKAGE_SORT_ORDER NATURAL)
SET(CMAKE_FIND_PACKAGE_SORT_DIRECTION DEC)
CMake构建了一组可能的包安装路径前缀。在每个前缀路径之下,含有多个目录可以用来搜索配置文件。下表列出了一些可以搜索的文件夹。每个条目都对应各自可能的系统环境(W:windows, U:UNIX; A:Apple)。
路径 | 系统 |
---|---|
(W) | |
(W) | |
(W) | |
(W) | |
(U) | |
(U) | |
(U) | |
(W/U) | |
(W/U) | |
(W/U) |
在上述表中,是大小写敏感的并对应于任意的或者NAEMS所指定的名称。
如果CMAKE_LIBRARY_ARCHITECTURE变量被设置后, lib/这个路径可以被使用。lib* 包括了一个或者多个值,如lib64, lib32, libx32, 或者lib。其中:
如果PATH_SUFFIXES被设定了,这这些后缀会在上标中每个条目的后面进行一一追加。
这一组安装前缀是通过以下步骤进行构建起来的。如果NO_DEFAULT_PATH被指定,那么所有的NO_* 选项将会被激活。
CMake 变量CMAKE_FIND_ROOT_PATH指定了一个或者多个目录, 则会预置多个其他的搜索目录(这里应该是将这个变量作为上述表格中的prefix)。默认情况是这个变量值是空的。
变量CMAKE_SYSROOT也可以被用来指明一个目录作为prefix。 设置CMAKE_SYSROOT同时也会带来其他影响。
这些变量在跨平台编译时指定目标环境根目录的时候非常有用。默认情况下是先搜索CMAKE_FIND_ROOT_PATH,然后再搜索CMAKE_SYSROOT目录,最后是搜索非根目录。这种默认的行为可以通过设CMAKE_FIND_ROOT_PATH_MODE_PACKAGE来进行调整。通过手动设置下列选项可以进行调整:
变量 | 功能 |
---|---|
CMAKE_FIND_ROOT_PATH_BOTH | Search in the order described above |
NO_CMAKE_FIND_ROOT_PATH | Do not use the CMAKE_FIND_ROOT_PATH variable |
ONLY_CMAKE_FIND_ROOT_PATH | Search only the re-rooted directories and directories below CMAKE_STAGING_PREFIX |
大多数情况下默认的搜索路径设计一般是从细到宽的设计。项目可以重写顺序通过多次调用带有NO_*的命令。
find_package ( PATHS paths... NO_DEFAULT_PATH)
find_package ()
一旦某个调用成功了则会对相应的变量进行设置并存储在缓存中,之后的调用则不会再进行搜索。
[1] CMake 官方文档
[2] find_package与CMake如何查找链接库详解