一    cmake帮助文档

find_package命令详解

1)  --help-command-list        cmake'内置命令'列表

2)  --help-comamnd <command>   command帮助文档

3)  --help-variable-list       完整CMAKE'内置变量'列表

4)  --help-module-list         现有的'模块'列表 -->'重点'

espidf中的cmakelist cmakelist find_package_搜索

espidf中的cmakelist cmakelist find_package_搜索_02

二    find_package语法

FIND_PACKAGE 命令用于'搜索'并加载'外部工程',其'隐含的变量'用于'标识'是否'搜索'到所需的'package_name'

(1)   Module模式的解读

cmake3 --help-command find_package  -->'find_package'的帮助文档

注意: 'Module'模式中 'REQUIRED'、COMPONENTS、EXACT、'QUIET'字段的解读

备注: 'MODULE'强制使用'module'模式,也即'module'找不到,则'error报错'

①     Module模式可用的属性

备注: 'Component'如何'理解'?

espidf中的cmakelist cmakelist find_package_帮助文档_03

②    Module模式是如何查找指定package的

espidf中的cmakelist cmakelist find_package_CMake_04

备注: 'Centos7.7'cmake默认是'没有'这个变量的

espidf中的cmakelist cmakelist find_package_CMake_05

espidf中的cmakelist cmakelist find_package_帮助文档_06

③    继续解读

Module模式:搜索'CMAKE_MODULE_PATH'指定路径下的'FindXXX.cmake'文件,'执行该文件'从而'找到XXX库'

备注: 具体'查找库'并给XXX_INCLUDE_DIRS和XXX_LIBRARIES两个'变量赋值的操作'由FindXXX.cmake模块完成

++++++++++++++'CMAKE_MODULE_PATH'指定的路径++++++++++++++

1)<CMAKE_ROOT>/share/cmake-x/Mdodules 

备注1:x表示'大'版本号,centos7中如果是'2.x.x'系列,则不指定;'3.x.x'系列指定为'3'

++++++++++++++'CMAKE_ROOT'的路径++++++++++++++

1)其中'CMAKE_ROOT'是你在'安装cmake'的时候的'系统路径'

2)如果'没有指定'安装路径,则是'系统默认'的路径,在我的系统中(Centos7.7)系统的默认路径是'/usr/local'

3)如果你在安装的过程中使用了'cmake -DCMAKE_INSTALL_PREFIX=自己dir路径' ,那么此时'CMAKE_ROOT'就代表那个你'写入'的路径 

备注: '$CMAKE_ROOT'的具体值可以通过CMake中'message命令'输出

小结: 这称为'模块(Module)'模式,也是'默认'的模式

++++++++++++++'实践'++++++++++++++

set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} ${CMAKE_CURRENT_SOURCE_DIR}/cmake)

说明: 基于'原来的','添加'一个'查找'路径-->'列表'

④  实践

C++ CMake 使用 Python3

1)指令如下

find_package(Python3 COMPONENTS Interpreter REQUIRED)

2)查找顺序

说明:没有哪个属性表明是'强制使用Config',所以优先'Module'模式,查找'FindPython3.cmake'文件,由于'没有定义CMAKE_MODULE_PATH',所以会从'系统/usr/share/camke3/Modules/'中查找

espidf中的cmakelist cmakelist find_package_搜索_07

3)查看该cmake文件

espidf中的cmakelist cmakelist find_package_帮助文档_08

内置'一些'变量:'Python3_FOUND'、'Python3_EXECUTABLE'

espidf中的cmakelist cmakelist find_package_搜索_09

espidf中的cmakelist cmakelist find_package_帮助文档_10

说明: 分为'两部分',一部分是'帮助文档(细细的阅读)',一部份是'cmake命令'

espidf中的cmakelist cmakelist find_package_帮助文档_11

espidf中的cmakelist cmakelist find_package_espidf中的cmakelist_12

4)测试

<Package>_FOUND -->'属性'

espidf中的cmakelist cmakelist find_package_搜索_13

(2)Config模式

①     Config模式可用的属性

取反: 不指定"CONFIG",不指定"NO_MODULE",也不使用"full signature"中的关键字,那就是在'Module'模式

espidf中的cmakelist cmakelist find_package_espidf中的cmakelist_14

②    Config模式是如何查找指定package的

espidf中的cmakelist cmakelist find_package_CMake_15

Config模式:搜索'XXX_DIR'指定路径下的'XXXConfig.cmake'文件,'执行'该文件从而'找到'XXX库

备注: 其中具体查找库'并给XXX_INCLUDE_DIRS'和'XXX_LIBRARIES'两个变量'赋值的操作'由'XXXConfig.cmake'模块完成

+++++++++++Config '搜索路径'+++++++++++

1)搜索xxx_DIR '指定'的路径

2)如果在CMakeLists.txt中'没有设置'这个cmake变量,也就是说'没有下面的指令': 

    set(xxx_DIR "xxxConfig.cmkae文件所在的路径")那么Cmake'就不会搜索'xxx_DIR指定的路径

3)Cmake 会在'/usr/local/lib/cmake/xxx/'、 '/usr/local/share/xxx' 中的xxxConfig.cmake文件

备注: 这个路径'不同的操作系统'存在差异,当前'Centos7.7'是'/usr/share/cmake{,3}/Modules/'

espidf中的cmakelist cmakelist find_package_CMake_16

③    继续解读

espidf中的cmakelist cmakelist find_package_帮助文档_17

espidf中的cmakelist cmakelist find_package_CMake_18

④    实践

场景: 由于Caffe安装时'没有安装'到系统目录,因此'无法自动找到'CaffeConfig.cmake,在'CMakeLists.txt'最前面'添加了一句话'之后就可以了

+++++++++++++++++++'配置步骤'+++++++++++++++++++

(1)'添加'CaffeConfig.cmake的搜索路径

set(Caffe_DIR /home/wzj/projects/caffe/build)

(2)查找'Caffe'模块

find_package(Caffe REQUIRED)

指令含义: 表示此包是'必须的(required)',如果'没有找到',构建程序'报错'并'终止'

首先:采用默认的'Module'模式,在'CMAKE_MODULE_PATH'中寻找'FindCaffee.cmake'文件,没有找到,则转下

然后:采用'Config'模式,在上面定义的'Caffe_DIR'路径中,搜索'CaffeConfig.cmkae文件'

备注:这里假设'Config'模式

(3)模块'是否'找到 -->'包状态变量判断'

if(NOT Caffe_FOUND)
  message(FATAL_ERROR"Caffe Not Found!")
endif(NOT Caffe_FOUND)

(4)找到则'加入''include_directories'目录

include_directories(${Caffe_INCLUDE_DIRS})

add_executable(useSSD ssd_detect.cpp)

target_link_libraries(useSSD${Caffe_LIBRARIES})

(3)小结

find_package与CMake如何查找链接库详解

1)cmake'默认'采取'Module'模式

2)如果Module模式'未找到'库,才会'采取Config'模式

也即:如果在Module的搜索路径'中没有找到'对应的'cmake file',则使用config模式

3)总之,Config模式是一个'备选策略'

补充:通常'库安装时'会拷贝一份'XXXConfig.cmake'到'系统'目录中,因此在'没有显式'指定'搜索路径时'也可以顺利'找到'

espidf中的cmakelist cmakelist find_package_搜索_19

参考博客