CmakeLists所遇命令用法总结

1 option命令:

形式:option(<variable> "<help_text>" [value])

简介:cmake中option起到编译开关的作用,CMakeLists.txt中option以前的语句,变量按未定义处理,option之后的语句,变量才被定义。另外,注意,option命令定义的变量不影响c或c++源码中#ifdef或者#ifndef逻辑判断

2 MESSAGE("text"):

在make的时候向控制台输出的提示信息命令语句

3 add_definitions的用法

功能描述:其功能与C/C++中的#define一样

实例如下:

源文件main.cpp

#include <iostream>
int main()
{
#ifdef TEST_IT_CMAKE
	std::cout<<"in ifdef"<<std::endl;
#endif
	std::cout<<"not in ifdef"<<std::endl;
}

CMakeLists.txt

cmake_minimum_required(VERSION 3.10)
project(optiontest)

add_executable(optiontest main.cpp)
option(TEST_IT_CMAKE "test" ON)
message(${TEST_IT_CMAKE})
if(TEST_IT_CMAKE)
	message("itis" ${TEST_IT_CMAKE})
	add_definitions(-DTEST_IT_CMAKE)
endif()

运行编译

// 第一种编译运行方法
mkdir build&& cd build
cmake ../ -DTEST_IT_CMAKE=OFF
make
./optiontest

// 第二种编译运行方法
mkdir build&& cd build
cmake ../ -DTEST_IT_CMAKE=ON
make
./optiontest

分析运行输出结果,就可以明白该指令的用法。

4 编译选项设置

两种设置方式

(1)通过add_compile_options命令

        add_compile_options命令添加的编译选项是针对所有编译器的(包括c和c++编译器)

#判断编译器类型,如果是gcc编译器,则在编译选项中加入c++11支持
if(CMAKE_COMPILER_IS_GNUCXX)
    add_compile_options(-std=c++11)
    message(STATUS "optional:-std=c++11")   
endif(CMAKE_COMPILER_IS_GNUCXX)

(2)通过set命令修改CMAKE_CXX_FLAGSCMAKE_C_FLAGS

        set命令设置CMAKE_C_FLAGSCMAKE_CXX_FLAGS变量则是分别只针对c和c++编译器

#判断编译器类型,如果是gcc编译器,则在编译选项中加入c++11支持
if(CMAKE_COMPILER_IS_GNUCXX)
    set(CMAKE_CXX_FLAGS "-std=c++11 ${CMAKE_CXX_FLAGS}")
    message(STATUS "optional:-std=c++11")   
endif(CMAKE_COMPILER_IS_GNUCXX)

 5 list的用法总结

list(LENGTH <list><output variable>)
list(GET <list> <elementindex> [<element index> ...]<output variable>)
list(APPEND <list><element> [<element> ...])
list(FIND <list> <value><output variable>)
list(INSERT <list><element_index> <element> [<element> ...])
list(REMOVE_ITEM <list> <value>[<value> ...])
list(REMOVE_AT <list><index> [<index> ...])
list(REMOVE_DUPLICATES <list>)
list(REVERSE <list>)
list(SORT <list>)

LENGTH            返回list的长度

GET              返回list中index的element到value中

APPEND            添加新element到list中

FIND             返回list中element的index,没有找到返回-1

INSERT           将新element插入到list中index的位置

REMOVE_ITEM      从list中删除某个element

REMOVE_AT       从list中删除指定index的element

REMOVE_DUPLICATES       从list中删除重复的element

REVERSE         将list的内容反转

SORT           将list按字母顺序排序

 6 cmake中find_package用法

参考如下链接find_package原理简介以及使用说明

cmake本身不提供任何关于搜索库的便捷方法,也不会对库本身的环境变量进行设置。它仅仅是按照优先级顺序在指定的搜索路径进行查找Findxxx.cmake文件和xxxConfig.cmake文件(其中xxx代表库的名字,特别注意的是有大小写之分),这两个文件大体上是没有区别的,cmake能够找到这两个文件中的任何一个,我们都能成功使用该库,也就是我们可以用库的内置好了Cmake变量。包含了库的头文件和库文件的路径信息,虽然库的作者一般会提供这两个文件,但是也会遇到安装完毕后找不到的情况。当我们在cmake..命令之后,Cmake 会读取执行CMakeLists.txt中的代码,当执行find_package()这条命令后,Cmake 就会从某些路径中找这Findxxx.cmake文件或者xxxConfig.cmake文件,Cmake找到任意一个之后就会执行这个文件,然后这个文件执行后就会设置好一些Cmake变量。比如下面的变量(NAME表示库的名字 比如可以用Opencv 代表Opencv库):

<NAME>_FOUND
<NAME>_INCLUDE_DIRS or <NAME>_INCLUDES
<NAME>_LIBRARIES or <NAME>_LIBRARIES or <NAME>_LIBS
<NAME>_DEFINITIONS

一般常用的就是xxx_FOUNDxxx_INCLUDE_DIRSxxx_LIBS,分别代表是否找到库的标志、库的头文件路径、库文件路径。find_package()有两种模式:Module模式Config模式,分别对应上面的Findxxx.cmake 和xxxConfig.cmake两个文件。cmake默认优先Module模式,而Config模式是备选项

Module模式(仅仅查找Findxxx.cmake文件):

Cmake会优先搜索CMAKE_MODULE_PATH指定的路径,如果在CMakeLists.txt中没有设置CMAKE_MODULE_PATH为存储Findxxx.cmake的路径,也就是说没有下面的指令:
set(CMAKE_MODULE_PATH "Findxxx.cmake文件所在的路径")

那么Cmake不会搜索CMAKE_MODULE_PATH指定的路径,此时Cmake会搜索第二优先级的路径,也就是<CMAKE_ROOT>/share/cmake-x.y/Mdodules (注意:x.y表示版本号。我的是3.10)。其中CMAKE_ROOT是你在安装Cmake的时候的系统路径,因为我并没有指定安装路径,所以是系统默认的路径,在我的系统中(ubuntu16.04)系统的默认路径是/usr/loacl,如果你在安装的过程中使用了
cmake -DCMAKE_INSTALL_PREFIX=自己dir路径 ,那么此时CMAKE_ROOT就代表那个你写入的路径 。刚刚说道第一优先级的路径搜索没有找到Findxxx.cmake文件,就会到第二优先级的路径下搜索。如果Cmake在两个路径下都没有找到Findxxx.cmake文件。那么Cmake就会进入Config模式。

Config模式(仅仅查找xxxConfig.cmake文件):

Cmake会优先搜索xxx_DIR 指定的路径。如果在CMakeLists.txt中没有设置这个cmake变量。也就是说没有下面的指令:
set(xxx_DIR "xxxConfig.cmkae文件所在的路径")

那么Cmake就不会搜索xxx_DIR指定的路径,此时Cmake 就会自动到第二优先级的路径下搜索,也就是/usr/local/lib/cmake/xxx/中的xxxConfig.cmake文件。

查看find_package()的结果

find_package(but_velodyne REQUIRED)
if (but_velodyne_FOUND)
  MESSAGE (STATUS "@@@@@@dern: ${ButVELODYNE_DEFINITIONS}")
  MESSAGE (STATUS "@@@@@@dern: ${ButVELODYNE_INCLUDE_DIRS}")
  MESSAGE (STATUS "@@@@@@dern: ${ButVELODYNE_LIBRARY_DIRS}")
else()
  MESSAGE (STATUS "@@@@@@dern: but_velodyne not found")
endif(but_velodyne_FOUND)

7 include_directions和find_package

参考链接:include_directories与find_package的联系与区别

include_directories

是用来提供找头文件路径的,打个比方,我现在想要#include"cv.h",但是这个cv.h的路径是/usr/local/include/opencv,那么我总不能在主函数头前写
#include “/usr/local/include/opencv/cv.h”吧,这个时候就用到include_directories了,它提供了一个搜索头文件暂时的根目录,即你可以在cmakelists中写上
include_directories(/usr/local/include)来让库文件搜索以/usr/local/include为基础,即在main函数前写上#include “opencv/cv.h"即可

find_package():可参考6

也就是只要找到了*.CMAKE,我们就能够给上图底部的几个变量赋路径

最后,记得将找到的库连接到我们的可执行文件上

target_link_libraries( imageBasics ${OpenCV_LIBS} )

图像增强代码的CMakeLists.txt

cmake_minimum_required( VERSION 2.8 )//版本要求

project( imageBasics )//工程名

set( CMAKE_CXX_FLAGS "-std=c++11" )//添加c++ 11标准支持

find_package( OpenCV 3 REQUIRED )//寻找OpenCV.CMakeLists,以此找到包,并赋值各库相关变量

include_directories( ${OpenCV_INCLUDE_DIRS} )//OpenCV_INCLUDE_DIRS是关于find_package的变量,
                                             //包含了一个路径,这样可以在代码中的#include做根目录
include_directories(/usr/local/include)//同上,找根目录

add_executable( imageBasics test_transform2.cpp )//添加对主函数的可执行文件

target_link_libraries( imageBasics ${OpenCV_LIBS} )//链接OpenCV库,OpenCV_LIBS为代表库可执行文件的变量
                                                   //$为取出变量中的值

在有的时候会出现find_package找不到 __Config.cmake, _-config.cmake
的情况,解决办法非常简单,因为这两个文件都是包含了package所需的所有路径变量,非常重要,没有它们find_package不会起效果,所以直接去根目录下搜到这两个文件,路径复制后,直接设置,如
$set(OpenCV_DIR /opt/ros/kinetic/share/OpenCV-3.3.1-dev)
_DIR其实就是这两个文件所存在的位置,设置好后直接就得到所有路径变量了

还有就是find_package请和include_directories(${OpenCV_INCLUDE_DIRS}) target_link_libraries( test ${OpenCV_LIBS})配合食用,三步走

find_package(OpenCV 3.3.1 REQUIRED)中间写版本可以在多个版本包共存的条件下拿到自己想要的包的Config.cmake文件的路径

  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值