前言
- cmake 过程中总是出现找不到模块,所以学习一下,最好要会写FindXXX.cmake
 
目录
参考
cmake wiki: how to find libraries
How_to_create_a_ProjectConfig.cmake_file
cmake documentation: home page
Find package example
Martin K, Hoffman B. Mastering CMake[M]. Kitware, 2015.
学习记录
基础知识
- 使用VERBOSE=1来检查各种构建选项。
 - 在/build/Release/…/CMakeFiles/${cmake_target}.dir/中,有四个文件,用作CMake对依赖项的分析:
- depend.make:存储依赖项信息
 - flag.make:存储编译选项,如果该文件改变,将重新编译
 - build.make:依赖项如何构建,如果该文件改变,CMake将重新计算依赖
 - DependInfo.cmake:当前项目中有哪些文件和哪些语言
 
 - add_library(foo STATIC foo1.c foo2.c)
- 注意第一个参数是目标名,第二个参数是目标的修饰词,如果没有这个修饰词,那么将检查环境变量BUILD_SHARED_LIBS,如果没有定义这个环境变量,则按默认,生成静态链接库
 
 - target_link_libraries(foo bar)
- bar可为:库名字,库的完整路径名和之前用add_library()指令生成的库名
 
 - 环境变量有局部特性:意味着子函数,子路径,子CMake指令中的变量名字不会影响上一个环境
 - 函数举例
 
1  | function(foo)  | 
- 循环举例
 
1  | set (items_to_buy apple orange pear beer)  | 
- CMake Cache
- 作用:缓存,下一次可以直接用;人机界面使用这个信息
 - 注意:一旦Cache中有了信息,则只能通过人机界面来修改?
 - 用法:option(USE_JPEG “DO you want to use jepg library?”),这句话会创建一个变量名存入Cache。
 - 直接使用CACHE option
 - set(USE_JPEG ON CACHE BOOL “include jpeg support?”)
 - ON:变量值;CACHE:选项;BOOL:变量类型;”include jepg …”:文档字符串
 
 
1  | find_library(TIFF_LIBRARY  | 
- find_library
- 当不同的系统,相同的库文件被安装在不同路径下时,就需要使用这个命令
 - 只需要库的base name,即不需要libtiff,libtiff2,或者tiff.so,tiff.so.2
 - find命令,会去${PATH}里面找文件
 - 命令会默认创建CACHE
 
 - find_path
- 当不同的系统,相同的头文件被安装在不同路径下时,就需要使用这个命令
 - 其他和find_library差不多
 
 - find_package
- ./Modules/里面有默认的FindXX.cmake,运行这个命令就相当于运行这个.cmake文件,如果找到模块,则赋予多个环境变量值
 
 
find_package详解
使用外部库
- CMake原生支持许多module的寻找,通过cmake –help-modul-list,可以查看,相关原生.cmake文件存放在/usr/share/cmake/Modules/
 
如果在网上找到了FindXXX.cmake文件
- 第一步,检查这个包是否是必须的,如果不是必须,将REQUIRED关键字去掉即可
 - 如果该包必须,则将此文件放入你的当前项目的./cmake/modules/中,然后在根目录的CMakeLists文件中,添加
1
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake/Modules/")
 
带有组件的库
- 注意,以下句子都是等同的
 
1  | 
  | 
- 会产生
_ _FOUND  
find_package工作机制
- 寻找Findxxx.cmake文件,首先到${CMAKE_MODULE_PATH}中找,然后在自己的/modules/中找。
 - 如果没有找到,则寻找
Config.cmake or -config.cmake,这些是一些库在安装时候自动生成的,不过一般不会被生成。  - 找到之后,生成以下变量
_FOUND _INCLUDE_DIRS or _INCLUDES _LIBRARIES or _LIBRARIES or _LIBS _DEFINITIONS 
 
pkg-config
- 当某一个库没有内建cmake支持时,无法生成Findxxx.cmake文件进行搜索,可以借助这个工具进行寻找。
 - 不过请注意:这个工具生成的结果不可靠
 
自己写findxxx.cmake
传统方法
- 注意,该文件名需要符合特定的规则
 - 使用find_package命令来找到这个包的依赖项。
 - 使用pkd-config来检测包含文件/库文件的目录
 - 使用find_path和find_library来确定库文件和头文件
- pkg-config的生成结果可以作为候选搜索目录
 - 添加一些一定会存在的目录
 - 命令执行后会生成变量
 
 - Set 
_INCLUDE_DIRS to _INCLUDE_DIR _INCLUDE_DIRS …  - Set 
_LIBRARIES to _LIBRARY _LIBRARIES …  - Call the find_package_handle_standard_args() macro to set the 
_FOUND variable and print a success or failure message.  
1  | # - Try to find LibXml2  | 
借助LibFindMacros宏
1  | # - Try to find ImageMagick++  |