CMake find_package

目录

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


Summary

介绍cmake 的find_package指令的概念、用法以及相关周边概念。阅读官方文档(find_package — CMake 3.22.0-rc3 Documentation) 能得到较为全面的理解。本Blog结合官方文档以及遇到的现实case,进行叙述。
 

1. find_package的两种搜索模式

1.1 Module Mode



In this mode, CMake searches for a file called Find<PackageName>.cmake, looking first in the locations listed in the 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<PackageName>.cmake 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 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<PackageName>.cmake的文件。该文件一般会定义头文件路径、lib路径等。首先在CMAKE_MODULE_PATH 指定的路径下搜索, 然后会在安装CMake时的一些模块路径下搜索。

一般的package中并不会提供Find<PackageName>.cmake文件,一般是由pgakage的使用者自己写这个文件,这种情况下会存在.cmake文件和package不一致问题,例如package突然更新了。
该模式只能对应baseic command signature.
 

1.2 Config Mode

In this mode, CMake searches for a file called <lowercasePackageName>-config.cmake or <PackageName>Config.cmake. It will also look for <lowercasePackageName>-config-version.cmake or <PackageName>ConfigVersion.cmake if version details were specified (see Config Mode Version Selection for an explanation of how these separate version files are used).

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会搜索名字为 <lowercasePackageName>-config.cmake or <PackageName>Config.cmake的文件,如果指定了版本,还需要搜索<lowercasePackageName>-config-version.cmake or <PackageName>ConfigVersion.cmake文件。 搜索路径和搜索顺序后面的会单独讲解。

这种文件通常由package的发布者提供,很可靠。
 

该模式可以对应baseic/full command signature.

两种Mode的选择


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 the CMAKE_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 a MODULE 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"的关键字
     

2 两种Signature

2.1 Basi signature

find_package(<PackageName> [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 <PackageName>_FOUND 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 where versionMin and versionMax 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.
 

2.2 full signature

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 <PackageName>_DIR is created to hold the directory containing the file. By default the command searches for a package with the name <PackageName>. If the NAMES option is given the names following it are used instead of <PackageName>.

The command searches for a file called <PackageName>Config.cmake or <lowercasePackageName>-config.cmake 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 <PackageName>_CONFIG.

All configuration files which have been considered by CMake while searching for the package with an appropriate version are stored in the <PackageName>_CONSIDERED_CONFIGS variable, and the associated versions in the <PackageName>_CONSIDERED_VERSIONS 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 <PackageName>_DIR 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.

2.3 Config Mode Search Procedure

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 <PackageName>_ROOT CMake variable and the <PackageName>_ROOT environment variable, where <PackageName> 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:

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:

4)...


2.4 Config Mode Version Selection

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 - 博客园

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
### 回答1: CMake 的 find_package 命令用于查找并加载指定的第三方库。使用 find_package 命令可以在构建项目时自动查找第三方库的安装目录,并将它们加入编译器和链接器的搜索路径中。例如: ``` find_package(Boost REQUIRED) include_directories(${Boost_INCLUDE_DIRS}) target_link_libraries(myTarget ${Boost_LIBRARIES}) ``` find_package 命令需要指定查找的库名称,可选的还有 REQUIRED, QUIET, NO_MODULE等参数。 ### 回答2: CMake是一种在跨平台软件开发过程中使用的自动化构建工具。使用CMake可以大大简化构建过程并使得跨平台开发更加容易。在CMake中,find_package是一个非常重要的命令,用于寻找和安装需要的外部软件包、库和依赖。 通过find_package,开发人员可以根据软件包的名称、版本和配置设置来指定其要安装的软件包。例如,如果一个软件包需要使用OpenCV,那么在CMake中需要使用find_package(OpenCV REQUIRED)命令,这条命令会在系统上查找安装OpenCV,并确保其可用。 find_package命令还有其他可选参数,例如COMPONENTS、VERSION和QUIET,这些参数可以根据开发需求来灵活设置。其中COMPONENTS选项是用于同时查找多个软件包,并在不同组件之间进行选择。VERSION选项可以指定软件包需要的版本号,以帮助开发人员确定使用哪个版本。QUIET选项可以禁止错误和警告消息,从而减少不必要的输出。 find_package的另一个重要的功能是分离了CMakeLists.txt文件中的构建和配置过程,这样可以使得CMakeLists.txt文件更加清晰和可读。在使用find_package时,需要定义一个包含Finder模块的CMake文件,该文件用于指定软件包的位置。例如,OpenCVConfig.cmake文件可以用于描述OpenCV的安装路径。开发人员可以根据实际需求编写自己的Finder模块来定位所需的软件包和库。 总之,使用CMake的find_package命令可以使得软件开发更加高效和精确,能够帮助开发人员轻松地管理软件包和库的依赖性,简化项目开发过程,同时也增强了跨平台开发的灵活性和可移植性。 ### 回答3: CMake是一款跨平台的构建工具,在构建项目时需要管理依赖库的安装和使用。而find_package函数就是CMake中用来管理依赖库的函数之一。 find_package函数用于查找系统中安装的库,其语法如下: find_package(PackageName [version] [EXACT] [QUIET] [MODULE] [REQUIRED] [[COMPONENTS] [list of components]]) 其中,PackageName表示需要查找的库的名称,version表示需要查找的库的版本号,EXACT用于确保找到的库的版本完全匹配所需的版本,QUIET用于控制输出信息,MODULE用于在指定查找路径中查找库,REQUIRED用于指定如果找不到库则停止构建,COMPONENTS用于指定需要使用库中的组件名称。 find_package函数会在以下位置查找库: 1. 环境变量CMAKE_PREFIX_PATH所指定的路径中查找库 2. 库安装目录中查找 3. 系统默认路径中查找 当find_package函数找到库后,变量${PackageName}_FOUND会被设置为TRUE,同时${PackageName}_INCLUDE_DIRS、${PackageName}_LIBRARIES等变量也会被设置为库的相关信息。 总之,find_packageCMake中很重要的函数之一,可以方便地管理依赖库的安装和使用,提高项目代码的可移植性。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

First Snowflakes

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值