CMake知识补充(未完代续)
写在前面
近来进行G2O优化库的学习,第一个demo程序就被cmake坑的很惨,之前对于cmake总感觉就是用着学着,但是这次踩坑之后发现这样的方式确实会浪费一些时间,特别是没有人带的情况下,但是现阶段自己也没能拿出大块的时间去学习cmake,所以特别的写这个博客,希望在以后的时间里能对cmake的知识进行进一步的完整,相信慢慢的积累总能达到一些效果。
关于find_package
这个命令是cmake里面应该算是最熟悉的命令了,最开始写opencv程序的时候就会照着别人的cmakelists写find_package(OpenCV REQUIRED),当时也试过,写成OPENCV或者opencv都会出问题,但是也没有深究,现在仔细研究了一下,算是补上当时的偷懒吧。
find_package的查找顺序
在cmake里面,find_package是有相应的查找顺序的,首先cmake会在模块路径下进行查找Find<Module>.cmake文件(这个文件名都是这样的,这里“<Module>”的内容就是find_package里面包的名字),具体的查找路径为:
1. 变量CMAKE_MODULE_PATH中的所有路径;
2. 查找cmake自己的模块库,位置在/usr/share/cmake-x.x/Modules里面;
3. ~/.cmake/packages/或者/usr/local/share/中的各个包目录下查找<Module>Config.cmake(OpenCV就在这个目录下);
那么在上述的过程中,首先我们必须知道说自己要找的模块名字,也就是上述<Module>的名字,因为这个决定了find_package里面模块的名称;其次就是手动加入查找的路径,比如G2O的程序,我们需要手动的将cmake_module文件夹(这个文件夹g2o提供了,里面有G2O,CSparse,Cholmod模块的.cmake文件)加入到查找路径中,一般使用如下语句把路径加入到查找链表中
list(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)
find_package之后的变量
我们知道,find_package过后,我们可以通过<Module>_FOUND进行是否查找到模块的判断,同样的,如果该标志位为真,则在整个cmakelists中会产生一些变量,多数博客讲一般产生如下变量:
<NAME>_FOUND
<NAME>_INCLUDE_DIRS or <NAME>_INCLUDES
<NAME>_LIBRARIES or <NAME>_LIBRARIES or <NAME>_LIBS
<NAME>_DEFINITIONS
但是今天发现其实并不是这样的,甚至有时候NAME的大小写都会变化了,那么具体的变量是什么呢?还是要从.cmake里面进行查找,这里以opencv和cholmod为例:
OpenCV的情况
我们先进入到/urs/local/share/OpenCV/文件夹下,打开OpenCVConfig.cmake文件,我们可以从注释中看到
我们可以看到,找到opencv模块之后会产生如下变量(这里列出最常用的):OpenCV_LIBS和OpenCV_INCLUDE_DIRS
所以在cmakelists中我们就要用这两个变量把opencv的库文件和头文件加入进来。
Cholmod的情况
同样的,我们打开Cholmod的.cmake文件,可以看到如下程序
可以看到我们在cmakelists需要使用的变量为CHOLMOD_INCLUDE_DIR和CHOLMOD_LIBRARIES,跟我的经历一样,一旦这个CHOLMOD_INCLUDE_DIR写成CHOLMOD_INCLUDE_DIRS或者Cholmod_INCLUDE_DIR,整个程序就找不到声明和定义。
所以可以看到,cmake里面的变量也不是一成不变的,而是根据.cmake文件的信息来的。
总结
1. find_package(NAME REQUIRED)中的NAME不是随便写的,而是要根据.cmake前面的模块名字写的;
2. 模块找到后,起产生的变量也不是一成不变或者有规律的,而是.cmake文件里面的变量名;
上一篇: CMake中include指令用法介绍
下一篇: cmake+CMakeLists的学习
推荐阅读