CMake中find_package的使用
Posted fengbingchun
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了CMake中find_package的使用相关的知识,希望对你有一定的参考价值。
CMake中的命令find_package用于查找指定的package。
find_package支持两种主要的搜索方法:注意:<PackageName>是区分大小写的
(1).Config mode(配置模式):使用该方法,find_package会查找通常由package本身提供的文件。在这种模式下,CMake会搜索名为<lowercasePackageName>-config.cmake或<PackageName>Config.cmake的文件,如OpenCV生成的库中的OpenCVConfig.cmake文件。如果指定了版本详细信息,它还将查找<lowercasePackageName>-config-version.cmake或<PackageName>ConfigVersion.cmake。config和version files通常作为package的一部分安装,因此它们往往比Find modules更可靠。它们通常包含对package内容的直接了解,因此在config或version files本身中不需要搜索或启发(searching or heuristics)。find_package的基本签名(basic signature)和完整签名(full signature)都支持这种模式。
config-file packages:config file是package附带的文本文件,用于定义CMake targets, variables, commands等等。config file是一个普通的CMake脚本,由find_package命令读入。config files通常可以在lib/cmake/<PackageName>匹配的目录中找到,如编译OpenCV 4.6.0源码时生成的OpenCVConfig.cmake文件在lib/cmake/opencv4目录下,config files也可能位于其它位置。<PackageName>通常是find_package命令第一个参数,甚至可能是唯一的参数。
config file必须命名为<PackageName>Config.cmake或<LowercasePackageName>-config.cmake。此文件是package的入口点。<PackageName>Config.cmake或<LowercasePackageName>-config.cmake也可能存在于同一目录中。CMake使用此文件来确定package的版本是否满足对find_package的调用中包含的任何版本约束。在调用find_package时指定版本是可选的,即使存在<PackageName>ConfigVersion.cmake文件。
如果找到<PackageName>Config.cmake文件并且满足任何版本约束(version constraint),则find_package命令认为已找到该package,并假定整个package按设计完成。
如果package的位置在CMake已知的目录中,则find_package调用应该成功。CMake已知的目录是特定于平台(platform-specific)的。例如,在Linux上使用标准系统包管理器(standard system package manager)安装的package将自动在/usr前缀中找到。在Windows上安装在Program Files中的package同样会被自动找到。
如果package位于CMake不知道的位置,例如/opt/lib,则不会在没有帮助的情况下自动找到它们。这是正常情况,CMake为用户提供了几种方法指定在哪里可以找到此类库。
CMAKE_PREFIX_PATH变量可以在调用CMake时设置。它被视为搜索config file的基本路径列表。安装在/opt/lib/somepackage中的package通常会安装config file,例如/opt/lib/somepackage/lib/cmake/SomePackageConfig.cmake。在这种情况下,应将/opt/lib/somepackage添加到CMAKE_PREFIX_PATH。
环境变量CMAKE_PREFIX_PATH也可以填充前缀以搜索package。与PATH环境变量一样,这是一个列表,但它需要使用特定于平台的环境变量列表项分隔符,如在Linux上为":",在Windows上为";"。
CMAKE_PREFIX_PATH变量在需要指定多个前缀的情况下提供了便利,或者当多个package在同一前缀下可用时。也可以通过设置匹配<PackageName>_DIR的变量来指定package的路径,例如SomePackage_DIR。注意,这不是前缀,而应该是包含config-style package文件的目录的完整路径,例如上面的/opt/lib/somepackage/lib/cmake。
(2).Module mode(模块模式):并非所有packages都支持CMake,许多不提供支持config modes所需的文件。对于这种情况,可以由项目(project)或CMake单独提供Find module文件。Find module通常是一种启发式实现(heuristic implementation),它知道package通常提供什么以及如何将该package呈现给项目(project)。由于Find module通常与package分开发布(distribute),因此它们不那么可靠。它们通常是单独维护的,并且可能遵循不同的发布时间表,因此它们很容易过时。在这种模式下,CMake搜索名为Find<PackageName>.cmake的文件,如OpenCV源码中cmake/FindCUDA.cmake文件。首先在CMAKE_MODULE_PATH中列出的位置中查找,然后在CMake安装提供的Find Modules中查找。如果找到该文件,则由CMake读取并处理该文件。该文件负责查找package、检查版本并生成任何需要的消息(message)。Find<PackageName>.cmake文件通常不由package本身提供。相反它通常由package外部的东西提供,例如操作系统、CMake本身、甚至是调用find_package命令的项目。Module mode仅被find_package的基本签名支持。
根据使用的参数,find_package可以使用上述方法之一或两者。
通过将选项限制为仅基本签名(basic signature),可以使用config mode和module mode来满足依赖关系。其它选项的存在可能会将调用限制为仅用两种方法中的一种,从而可能降低find_package查找依赖项的能力。
Find Module Files:如果FindSomePackage.cmake文件可用,仍然可以使用find_package命令找到不提供config file的package。这些Find module files与config files的不同之处在于:
A.Find module files不应由package本身提供。
B.Find<PackageName>.cmake文件的可用性并不表示package或package的任何特定部分的可用性。
C.CMake不会在CMAKE_PREFIX_PATH变量中指定的位置搜索Find<PackageName>.cmake文件。相反,CMake在CMAKE_MODULE_PATH变量给定的位置搜索此类文件。用户在运行CMake时设置CMAKE_MODULE_PATH是很常见的,CMake projects通常会附加到(append to)CMAKE_MODULE_PATH以允许使用本地Find module files。
D.CMake为某些第三方packages提供Find<PackageName>.cmake文件。这些文件由CMake维护,并且这些文件落后于与其关联的packages的最新版本并不罕见。通常,新的Find modules不再添加到CMake。
(3).FetchContent redirection mode:3.24版本中引入。对find_package的调用可以在内部重定向到FetchContent module提供的package。对调用者而言,此行为类似于Config mode,只是绕过了搜索逻辑并且不使用组件信息。
当未重定向到FetchContent提供的package时,由find_package参数决定使用Module mode还是Config mode。
当使用基本签名时,find_package首先在Module mode下搜索。如果未找到package,则搜索回退到Config mode。用户可以将CMAKE_FIND_PACKAGE_PREFER_CONFIG变量设置为true以反转优先级并指示CMake在返回到Module mode之前首先使用Config mode进行搜索。也可以强制基本签名仅使用带有MODULE关键字的Module mode。如果使用完整签名,则find_package仅在Config mode下搜索。
在可能的情况下,用户代码通常应该使用基本签名来查找package,因为这样可以在任何mode下找到package。
Imported Targets:表示一个预先存在的依赖性。通常这样的targets是由上游package定义的,应该被视为不可变的。在声明一个Imported Target之后,可以像使用任何其它常规target一样,使用诸如target_compile_definitions, target_include_directories, target_compile_options或target_link_libraries之类的命令来调整其target属性。
config files和Find module files都可以定义Imported Targets。这些通常具有SomePrefix::ThingName形式的名称。
find_package的基本签名(Basic Signature)如下:
find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
[REQUIRED] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...]
[REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]
[GLOBAL]
[NO_POLICY_SCOPE]
[BYPASS_PROVIDER]
)
Module和Config modes都支持基本签名。选项包括:无论使用何种模式,都会设置一个<PackageName>_FOUND变量来指示是否找到了package。当找到package时,可以通过package本身记录的其它变量和导入的目标(Imported Targets)来提供package特定的信息(package-specific information)。
(1).MODULE:意味着只能使用Module mode来查找package,而不能回退到Config mode。示例代码段如下:
find_package(OpenCV) # Found OpenCV: /usr (found version "4.5.4")
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 1
message("OpenCV_INCLUDE_DIRS: $OpenCV_INCLUDE_DIRS") # OpenCV_INCLUDE_DIRS: /usr/include/opencv4
find_package(OpenCV MODULE) # CMake Warning at test_find_package.cmake:10 (find_package): No "FindOpenCV.cmake" found in CMAKE_MODULE_PATH
message("CMAKE_MODULE_PATH: $CMAKE_MODULE_PATH") # CMAKE_MODULE_PATH:
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 0
(2).QUIET:禁用消息性消息(disables informational messages),包括那些指示如果package不是REQUIRED则无法找到的消息。示例代码段如下:
find_package(OpenCV QUIET) # 不会再显示: Found OpenCV: /usr (found version "4.5.4")
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 1
find_package(OpenCV MODULE QUIET) # 不会再显示: CMake Warning at test_find_package.cmake:17 (find_package): No "FindOpenCV.cmake" found in CMAKE_MODULE_PATH
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 0
(3).REQUIRED:如果找不到package,则REQUIRED选项会停止处理并触发错误消息。示例代码段如下:
find_package(OpenCV MODULE REQUIRED) # CMake Error at test_find_package.cmake:20 (find_package): No "FindOpenCV.cmake" found in CMAKE_MODULE_PATH
(4).COMPONENTS:此关键字之后可能会列出所需组件的特定于package(package-specific)列表。如果不能满足这些组件中的任何一个,则认为未找到整个package。如果还存在REQUIRED选项,则将其视为fatal error,否则仍会继续执行。作为一种简写模式,如果存在REQUIRED选项,则可以省略COMPONENTS关键字,并且可以在REQUIRED之后直接列出所需的组件。示例代码段如下:
find_package(OpenCV COMPONENTS opencv_core) # Found OpenCV: /usr (found version "4.5.4") found components: opencv_core
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 1
find_package(OpenCV COMPONENTS opencv_xxxx) # Could NOT find OpenCV (missing: opencv_xxxx) (found version "4.5.4"))
# CMake Warning at test_find_package.cmake:25 (find_package): Found package configuration file:
# /usr/lib/x86_64-linux-gnu/cmake/opencv4/OpenCVConfig.cmake
# but it set OpenCV_FOUND to FALSE so package "OpenCV" is considered to be NOT FOUND.
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 0
(5).OPTIONAL_COMPONENTS:其它可选组件可能会在OPTIONAL_COMPONENTS之后列出。如果这些都不能满足,只要满足所有必需的组件,仍然可以认为整个package都找到了。
可用组件的集合及其含义由target package定义。示例代码段如下:
find_package(OpenCV COMPONENTS opencv_core opencv_highgui) # Found OpenCV: /usr (found version "4.5.4") found components: opencv_core opencv_highgui
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 1
find_package(OpenCV COMPONENTS opencv_core opencv_highgui OPTIONAL_COMPONENTS opencv_xxxx opencv_yyyy) # Found OpenCV: /usr (found version "4.5.4") found components: opencv_core opencv_highgui missing components: opencv_xxxx opencv_yyyy
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 1
(6).REGISTRY_VIEW:3.24版本中引入。指定应要查询的注册表视图(registry views)。此选项仅在Windows平台上有意义,在其它平台上将被忽略。
(7).GLOBAL:3.24版本中引入。指定此关键字会将所有imported targets提升到导入项目(improting project)的全局范围。或者可以通过设置CMAKE_FIND_PACKAGE_TARGETS_GLOBAL变量来启用此功能。
(8).version:此参数请求找到的package应该兼容的版本。有两种可能的形式可以指定它:
单个版本(single version):格式为:major[.minor[.patch[.tweak]]],其中每个组件都是一个数值。
版本范围(version range):3.19版本中引入。格式为:versionMin...[<]versionMax,其中versionMin和versionMax具有与单个版本相同的格式和约束。默认情况下,两个端点都包括在内。通过指定<,将排除上端点(the upper end point will be excluded)。
find_package(OpenCV 3.4.2) # Found OpenCV: /opt/opencv3.4.2 (found suitable version "3.4.2", minimum required is "3.4.2")
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 1
message("OpenCV_INCLUDE_DIRS: $OpenCV_INCLUDE_DIRS") # OpenCV_INCLUDE_DIRS: /opt/opencv3.4.2/include;/opt/opencv3.4.2/include/opencv
find_package(OpenCV 2.4.13.7) # CMake Warning at test_find_package.cmake:41 (find_package):
# Could not find a configuration file for package "OpenCV" that is compatible with requested version "2.4.13.7".
# The following configuration files were considered but not accepted:
# /opt/opencv3.4.2/share/OpenCV/OpenCVConfig.cmake, version: 3.4.2
# /usr/lib/x86_64-linux-gnu/cmake/opencv4/OpenCVConfig.cmake, version: 4.5.4
# /lib/x86_64-linux-gnu/cmake/opencv4/OpenCVConfig.cmake, version: 4.5.4
# /opt/opencv3.1/share/OpenCV/OpenCVConfig.cmake, version: 3.1.0
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 0
(9).EXACT:此选项要求version完全匹配。此选项与version range的规范不兼容。
find_package(OpenCV 3.4.2) # Found OpenCV: /opt/opencv3.4.2 (found suitable version "3.4.2", minimum required is "3.4.2")
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 1
message("OpenCV_INCLUDE_DIRS: $OpenCV_INCLUDE_DIRS") # OpenCV_INCLUDE_DIRS: /opt/opencv3.4.2/include;/opt/opencv3.4.2/include/opencv
find_package(OpenCV 3.0.0) # Found OpenCV: /opt/opencv3.4.2 (found suitable version "3.4.2", minimum required is "3.0.0")
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 1
find_package(OpenCV 3.0.0 EXACT) # CMake Warning at test_find_package.cmake:57 (find_package):
# Could not find a configuration file for package "OpenCV" that exactly matches requested version "3.0.0".
# The following configuration files were considered but not accepted:
# /opt/opencv3.4.2/share/OpenCV/OpenCVConfig.cmake, version: 3.4.2
# /usr/lib/x86_64-linux-gnu/cmake/opencv4/OpenCVConfig.cmake, version: 4.5.4
# /lib/x86_64-linux-gnu/cmake/opencv4/OpenCVConfig.cmake, version: 4.5.4
# /opt/opencv3.1/share/OpenCV/OpenCVConfig.cmake, version: 3.1.0
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 0
find_package的完整签名(Full Signature)如下:
find_package(<PackageName> [version] [EXACT] [QUIET]
[REQUIRED] [[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS components...]
[CONFIG|NO_MODULE]
[GLOBAL]
[NO_POLICY_SCOPE]
[BYPASS_PROVIDER]
[NAMES name1 [name2 ...]]
[CONFIGS config1 [config2 ...]]
[HINTS path1 [path2 ... ]]
[PATHS path1 [path2 ... ]]
[REGISTRY_VIEW (64|32|64_32|32_64|HOST|TARGET|BOTH)]
[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_INSTALL_PREFIX]
[NO_CMAKE_SYSTEM_PACKAGE_REGISTRY]
[CMAKE_FIND_ROOT_PATH_BOTH |
ONLY_CMAKE_FIND_ROOT_PATH |
NO_CMAKE_FIND_ROOT_PATH]
)
(1).CONFIG|NO_MODULE:CONFIG选项、同义的NO_MODULE选项或使用基本签名中未指定的选项都强制执行纯Config mode。在纯Config mode下,该命令会跳过Module mode搜索并立即进行Config mode搜索。
find_package(OpenCV 3.1.0 EXACT CONFIG)
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 1
message("OpenCV_INCLUDE_DIRS: $OpenCV_INCLUDE_DIRS") # OpenCV_INCLUDE_DIRS: /opt/opencv3.1/include/opencv;/opt/opencv3.1/include
find_package(OpenCV 4.5.4 EXACT NO_MODULE) # Found OpenCV: /usr (found suitable exact version "4.5.4")
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 1
message("OpenCV_INCLUDE_DIRS: $OpenCV_INCLUDE_DIRS") # OpenCV_INCLUDE_DIRS: /usr/include/opencv4
(2).NAMES:Config mode搜索试图定位要找到的package提供的配置文件。创建一个名为<PackageName>_DIR的缓存条目(cache entry)来保存包含该文件的目录。默认情况下,find_package搜索名称为<PackageName>。如果给出了NAMES选项,则使用它后面的名称而不是<PackageName>。
find_package(opencv) # CMake Warning at test_find_package.cmake:74 (find_package):
# By not providing "Findopencv.cmake" in CMAKE_MODULE_PATH this project has
# asked CMake to find a package configuration file provided by "opencv", but CMake did not find one.
# Could not find a package configuration file provided by "opencv" with any of the following names:
# opencvConfig.cmake
# opencv-config.cmake
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND:
find_package(opencv NAMES OpenCV) # Found OpenCV: /usr (found version "4.5.4")
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: TRUE
(3).CONFIGS:find_package为每个指定的名称搜索名为<PackageName>Config.cmake或<lowercasePackageName>-config.cmake的文件。可以使用CONFIGS选项给出一组可能的配置文件名的替换。Config mode搜索过程如下所示:一旦找到,就会检查任何版本约束(any version constraint is checked),如果满足,则CMake读取并处理配置文件。由于该文件是由package提供的,因此它已经知道package内容的位置。配置文件的完整路径存储在cmake变量<PackageName>_CONFIG中。
# 手动copy一份/opt/opencv3.1到/opt/opencv,并将/opt/opencv/share/OpenCV/OpenCVConfig.cmake调整为/opt/opencv/share/opencv/cv_config.cmake
set(OpenCV_DIR "/opt/opencv/share/opencv/")
find_package(OpenCV NO_DEFAULT_PATH) # Could NOT find OpenCV (missing: OpenCV_DIR)
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 0
set(OpenCV_DIR "/opt/opencv/share/opencv/")
find_package(OpenCV CONFIGS cv_config.cmake NO_DEFAULT_PATH)
message("OpenCV_INCLUDE_DIRS: $OpenCV_INCLUDE_DIRS") # OpenCV_INCLUDE_DIRS: /opt/opencv/include/opencv;/opt/opencv/include
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 1
message("OpenCV_CONFIG: $OpenCV_CONFIG") # OpenCV_CONFIG: /opt/opencv/share/opencv/cv_config.cmake
message("OpenCV_CONSIDERED_CONFIGS: $OpenCV_CONSIDERED_CONFIGS") # OpenCV_CONSIDERED_CONFIGS: /opt/opencv/share/opencv/cv_config.cmake
message("OpenCV_CONSIDERED_VERSIONS: $OpenCV_CONSIDERED_VERSIONS") # OpenCV_CONSIDERED_VERSIONS: unknown
CMake在搜索具有适当版本的package时考虑的所有配置文件都存储在<PackageName>_CONSIDERED_CONFIGS变量中,相关版本存储在<PackageName>_CONSIDERED_VERSIONS变量中。
如果找不到package配置文件,除非指定QUIET参数,否则CMake将生成描述问题的错误。如果指定了REQUIRED并且未找到package,则会生成致命错误(fatal error)并且配置步骤停止执行(configure step stops executing)。如果<PackageName>_DIR已设置为不包含配置文件的目录,CMake将忽略它并从头开始搜索。
find_package(OpenCV) # Found OpenCV: /usr (found version "4.5.4")
message("OpenCV_FOUND: $OpenCV_FOUND") # OpenCV_FOUND: 1
message("OpenCV_CONSIDERED_CONFIGS: $OpenCV_CONSIDERED_CONFIGS") # OpenCV_CONSIDERED_CONFIGS: /usr/lib/x86_64-linux-gnu/cmake/opencv4/OpenCVConfig.cmake
message("OpenCV_CONSIDERED_VERSIONS: $OpenCV_CONSIDERED_VERSIONS") # OpenCV_CONSIDERED_VERSIONS: 4.5.4
message("CMAKE_LIBRARY_ARCHITECTURE: $CMAKE_LIBRARY_ARCHITECTURE") # CMAKE_LIBRARY_ARCHITECTURE: x86_64-linux-gnu
message("FIND_LIBRARY_USE_LIB64_PATHS: $FIND_LIBRARY_USE_LIB64_PATHS") # FIND_LIBRARY_USE_LIB64_PATHS:
Config mode搜索过程:无论是完整签名还是基本签名,当使用Config mode时都会应用此搜索过程
(1).3.24版本中引入:所有对find_package的调用(即使在Module mode下)首先在CMAKE_FIND_PACKAGE_REDIRECTS_DIR目录中查找config package file。
FetchContent module,甚至project本身,可能会将文件写入该位置,以将find_package调用重定向到project已提供的内容。如果在该位置未找到config package file,则搜索将按照下面描述的逻辑进行:
(2).CMake为package构造了一组可能的安装前缀。在每个前缀下搜索几个目录以查找配置文件。下表显示了搜索的目录:每个条目(each entry)都适用于遵循Windows(W), UNIX(U), 或Apple(A)约定的安装树(installation trees)
<prefix>/ (W)
<prefix>/(cmake|CMake)/ (W)
<prefix>/<name>*/ (W)
<prefix>/<name>*/(cmake|CMake)/ (W)
<prefix>/<name>*/(cmake|CMake)/<name>*/ (W)
<prefix>/(lib/<arch>|lib*|share)/cmake/<name>*/ (U)
<prefix>/(lib/<arch>|lib*|share)/<name>*/ (U)
<prefix>/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/ (U)
<prefix>/<name>*/(lib/<arch>|lib*|share)/cmake/<name>*/ (W/U)
<prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/ (W/U)
<prefix>/<name>*/(lib/<arch>|lib*|share)/<name>*/(cmake|CMake)/ (W/U)
<prefix>/<name>.framework/Resources/ (A)
<prefix>/<name>.framework/Resources/CMake/ (A)
<prefix>/<name>.framework/Versions/*/Resources/ (A)
<prefix>/<name>.framework/Versions/*/Resources/CMake/ (A)
<prefix>/<name>.app/Contents/Resources/ (A)
<prefix>/<name>.app/Contents/Resources/CMake/ (A)
在所有情况下,<name>都被视为不区分大小写,并且对应于任何指定的名称(<PackageName>或由NAMES给出的名称)
(3).如果设置了CMAKE_LIBRARY_ARCHITECTURE变量,则启用带有lib/<arch>的路径。lib*包括一个或多个值lib64, lib32, libx32或lib(按该顺序搜索):
A.如果FIND_LIBRARY_USE_LIB64_PATHS属性设置为TRUE,则在64位平台上搜索具有lib64的路径。
B.如果FIND_LIBRARY_USE_LIB32_PATHS属性设置为TRUE,则在32位平台上搜索具有lib32的路径。
C.如果FIND_LIBRARY_USE_LIBX32_PATHS属性设置为TRUE,则在x32 ABI平台上搜索具有libx32的路径。
D.总是搜索lib路径。
(4).3.24版本中更改:在Windows平台上,可以使用专用语法将注册表查询作为通过HINTS和PATHS关键字指定的目录的一部分。在所有其它平台上,此类规范将被忽略。
(5).3.24版本中引入:可以指定REGISTRY_VIEW管理Windows注册表查询作为PATHS和HINTS的一部分。
指定必须要查询的注册表视图(registry views)。此选项仅在Windows平台上有意义,在其它平台上将被忽略。如果未指定,则在CMP0134策略为NEW时使用TARGET view。
(6).如果指定了PATH_SUFFIXES,则后缀将一个接一个地附加到每个(W)或(U)目录条目(directory entry)。
(7).如果指定了NO_DEFAULT_PATH,则启用所有NO_*选项。
以上测试代码搜索本机中的OpenCV头文件,本机中有多个版本的OpenCV库:
(1).4.5.4:头文件存放路径,系统默认的安装路径,通过命令sudo apt install libopencv-dev安装:/usr/include/opencv4/; OpenCVConfig.cmake存放路径:/usr/lib/x86_64-linux-gnu/cmake/opencv4/
(2).3.1:头文件存放路径:/opt/opencv3.1/include/; OpenCVConfig.cmake存放路径:/opt/opencv3.1/share/OpenCV/
(3).3.4.2:头文件存放路径:/opt/opencv3.4.2/include/; OpenCVConfig.cmake存放路径:/opt/opencv3.4.2/share/OpenCV/
执行上述测试代码需要3个文件:build.sh, CMakeLists.txt, test_find_package.cmake
build.sh内容如下:
#! /bin/bash
# supported input parameters(cmake commands)
params=(function macro cmake_parse_arguments \\
find_library find_path find_file find_program find_package \\
cmake_policy)
usage()
echo "Error: $0 needs to have an input parameter"
echo "supported input parameters:"
for param in $params[@]; do
echo " $0 $param"
done
exit -1
if [ $# != 1 ]; then
usage
fi
flag=0
for param in $params[@]; do
if [ $1 == $param ]; then
flag=1
break
fi
done
if [ $flag == 0 ]; then
echo "Error: parameter \\"$1\\" is not supported"
usage
exit -1
fi
if [[ ! -d "build" ]]; then
mkdir build
cd build
else
cd build
fi
echo "==== test $1 ===="
cmake -DTEST_CMAKE_FEATURE=$1 ..
CMakeLists.txt内容如下:
cmake_minimum_required(VERSION 3.22)
project(cmake_feature_usage)
message("#### current cmake version: $CMAKE_MAJOR_VERSION.$CMAKE_MINOR_VERSION.$CMAKE_PATCH_VERSION")
include(test_$TEST_CMAKE_FEATURE.cmake)
message("==== test finish ====")
test_find_package.cmake内容:为上面所有的示例代码
执行可能的结果如下图所示:
GitHub: https://github.com/fengbingchun/Linux_Code_Test
以上是关于CMake中find_package的使用的主要内容,如果未能解决你的问题,请参考以下文章
Cmake中find_package命令的搜索模式之模块模式(Module mode)
find_package的默认搜索路径是什么( )使用cmake时的功能?