find_package¶
为什要使用find_package指令¶
find_package的功能和pkg-config类似, 用来提取一个项目的元信息, 包括: 头文件包含路径, 链接参数, 项目中定义的宏等.
可以方便我们的使用, 且不用考虑由于导入这个项目而带来的间接依赖.
find_package的两种查找模式¶
Module模式查找
CMAKE_MODULE_PATH路径下的FindXXX.cmake文件(Find Module命名为:Findxxx.cmake); 如果没有找到,再去cmake自带的模块目录<CMAKE_ROOT>/share/cmake-x.y/Modules/下去查找. 通过该Finddxxx.cmake来获取该package的元信息;Config模式查找
XXX_DIR路径下的xxxConfig.cmake文件; 如果没有找到, 再去/usr/local/lib/cmake/xxx/中查找; 通过xxxConfig.cmake文件获取该package的元信息.
默认情况下, cmake采用Module模式查找, 如果没有找到, 再采用Config模式查找.
find_package的使用¶
Reduced Signature:
find_package(<package> [version] [EXACT] [QUIET] [MODULE]
[REQUIRED] [[COMPONENTS] [components...]])
<package>- 要查找的package;[version]- 指定版本号, 格式为:major[.minor[.patch]];[EXACT]- 精确匹配版本号;[QUIET]- TheQUIEToption disables messages if the package cannot be found;[MODULE]- 表示只以MODULE的方式查找;[REQUIRED]- 表示该包是必须的, 如果没有找到就停止并退出;[COMPONENTS]- 指出该package依赖的组件.如果指定了
REQUIRED选项, 可以将依赖的组件列在REQUIRED后面;
使用find_package进行查找后, 可以使用以下变量来判断package是否找到, 以及package的信息:
<package>_FOUND
True- Found;False- Not Found.
<package>_INCLUDE_DIRSor<package>_INCLUDES头文件的包含路径.
<package>_LIBRARIESor<package>_LIBS链接参数.
如果找到了头文件包含路径, 可以使用include_directories来添加头文件包含路径;
如果找到了链接参数, 可以使用target_link_libraries来添加链接参数.
为了支持各种常见的库和包, CMake自带了很多模块.
cmake --help-module-list- 查看CMake支持的模块列表;Linux下cmake存放自带模块的路径是:
/usr/share/cmake/Modules/;cmake --help-module <模块文件名>- 查看Find Module中定义的变量.
Example:
- 以bzip2库为例, 在CMake中有一个
FindBZip2.cmake模块, 只要使用find_package(BZip2)指令进行查找, cmake就会执行查找操作并自动给一些变量赋值以反应查找结果, 之后就可以在cmake脚本中检查查找结果并使用;cmake_required_minimum(VERSION 2.8.0) project(helloworld) add_executable(helloworld hello.c) find_package(BZip2) if (BZip2_FOUND) inlcude_directories(${BZip2_INCLUDES}) target_link_libraries(helloworld ${BZip2_LIBS}) endif()
为自己的项目编写Find Modules¶
采用Module模式(虽然Config模式支持更强大的功能, 但对多数的应用而言, Module模式足够了);
基本思路是, 在项目中生成一个Findxxx.cmake文件, 并在安装时将其安装到适当的位置;