find_package 主要用于查找指定的 package,主要支持两种搜索方法:
- Config mode:查找 xxx-config.cmake或 xxxConfig.cmake的文件,如OpenCV库的OpenCVConfig.cmake
- Module mode:查找Findxxx.cmake文件,如OpenCV库中的FindCUDA.cmake
详细的find_package介绍参考链接:find_package详解
目录
一、检索模式
find_package 有两种检索模式,这两种模式存在优先级,如果其中一种检索模式没有找到所需模块,就会启用另一种模式。
不同模式下,find_package 使用的检索路径也会有所不同。
1、Config mode(配置模式)
该模式下查找的是 <lowercasePackageName>-config.cmake 或 <PackageName>Config.cmake的文件。xxx-config.cmake 文件一般是小写开头,XXXConfig.cmake 文件一般是大写开头。
cmake 通过 CMAKE_PREFIX_PATH 设置配置模式的搜索路径:
# CMAKE_PREFIX_PATH 是配置模式的搜索路径
# 方式一
set(CMAKE_PREFIX_PATH 搜索路径)
# 方式二
list(APPEND CMAKE_PREFIX_PATH 搜索路径)
2、Module mode(模块模式)
该模式下查找的是 Find<PackageName>.cmake 的文件。
cmake 通过 CMAKE_MODULE_PATH 设置模块模式的搜索路径:
# CMAKE_MODULE_PATH 是模块模式的默认搜索路径
# 方式一
set(CMAKE_MODULE_PATH xxx)
# 方式二
list(APPEND CMAKE_MODULE_PATH 搜索路径)
二、find_package 的格式及内置变量
find_package 可以在搜索路径和默认路径(环境变量)中查找指定的库或者模块。无论使用哪种模式,都会设置一个 <PackageName>_FOUND 变量来指示是否找到了package。
1、签名格式
尖括号代表必填内容,中括号里的内容代表选择性填写内容
find_package(<PackageName> [version] # 指定要查找的库或者模块(版本号可选)
[EXACT] # 要求version完全匹配
[QUIET] # 无论找到与否,都不产生任何提示性消息
[REQUIRED] # 要求必须找到 xxx.cmake,找不到就提示报错
[[COMPONENTS] [components...]]
[OPTIONAL_COMPONENTS [components...]]
[MODULE] # 仅使用模块模式
[CONFIG|NO_MODULE] # 仅使用配置模式(两种写法是等效的)
[GLOBAL]
[NO_POLICY_SCOPE]
[BYPASS_PROVIDER]
)
(1) [[COMPONENTS] [components...]]
查找 Package 中的指定模块,COMPONENTS 跟的是一个列表,只要列表中任意一个模块没有被找到,则认为整个 Package 没有被找到,即 <PackageName>_FOUND 为 false
(如果存在REQUIRED选项,则可以省略COMPONENTS关键字)
# 如果opencv_core、opencv_highgui任意一者没有被找到
# 则认为 OpenCV 库没有找到
# 即 OpenCV_FOUND 为false
find_package(OpenCV COMPONENTS opencv_core opencv_highgui)
(2) [OPTIONAL_COMPONENTS [components...]]
OPTIONAL_COMPONENTS 跟的也是一个列表,只要列表中的某一项被找到了,就认为是找到了,即 <PackageName>_FOUND 为 true
# 即便是没找到 opencv_xxx,但是找到了opencv_core
# 则认为 OpenCV 库已被找到
# 即 OpenCV_FOUND 为true
find_package(OpenCV COMPONENTS opencv_core opencv_highgui opencv_xxx)
2、find_package 内置变量
find_package 一般都内置了一些变量:
- <PackageName>_FOUND:可以判断是否找到对应的包或者模块
- <PackageName>_INCLUDE_DIR:表示头文件目录(前提是包被找到才会被自动设置)
- <PackageName>_LIBRARIES:表示库文件
以查找 OpenCV 库为例:
# 检索OpenCV库
find_package(OpenCV REQUIRED)
add_executable(main src/main.cpp)
if(OpenCV_FOUND)
# 引入头文件目录
include_directories(${OpenCV_INCLUDE_DIRS})
# 链接库文件
target_link_libraries(main ${OpenCV_LIBRARIES})
else(OpenCV_FOUND)
message(FATAL_ERROR "OpenCV library not found")
endif()
注意:${OpenCV_LIBRARIES} 只是库名,不代表库目录,相当于在其他地方做了如下操作
set(OpenCV_LIBRARIES opencv_core opencv_calib3d opencv_highgui )