目录

  • 基础
  • 增加依赖库
  • 将 .cpp文件 编译成一个库,供其他文件调用:
  • 变量名
  • ORB-SLAM2的例子
  • 补充
    • list
    • 自动检测编译器是否支持C++11
    • 警告:检测到时钟错误。您的创建可能是不完整的。

基础

首先构建一个CMake目录。ubuntu下的CMake项目通常有几个文件夹组成。
一般

  • bin文件夹用来存放编译好的可执行二进制文件
  • src用来放源代码
  • lib用来放编译好的库文件
  • include用来放头文件

基本的CMakeLists.txt:

CMAKE_MINIMUM_REQUIRED(VERSION 2.8) # 设定版本
PROJECT(git_test) # 设定工程名
set(CMAKE_CXX_COMPILER "g++") # 设定编译器#设定可执行二进制文件的目录
SET( EXECUTABLE_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/bin)#设定存放编译出来的库文件的目录
SET( LIBRARY_OUTPUT_PATH ${PROJECT_SOURCE_DIR}/lib)#并且把该目录设为连接目录
LINK_DIRECTORIES( ${PROJECT_SOURCE_DIR}/lib)
#link_directories()#设定头文件目录
INCLUDE_DIRECTORIES( ${PROJECT_SOURCE_DIR}/include)
#include_directories()#增加子文件夹,也就是进入源代码文件夹继续构建
ADD_SUBDIRECTORY( ${PROJECT_SOURCE_DIR}/src)

增加依赖库

# 增加PCL库的依赖
FIND_PACKAGE( PCL REQUIRED COMPONENTS common io )# 增加opencv的依赖
FIND_PACKAGE( OpenCV REQUIRED )# 将 -D 定义标志添加到源文件的编译中。
# 例如在编译某些项目源码的时候,有提示可以使用相关cmake设置,指令使用方式为 cmake -DTHIRD_PARTY_MIRROR=aliyun ..
ADD_DEFINITIONS( ${PCL_DEFINITIONS} )
#设定头文件目录
INCLUDE_DIRECTORIES( ${PCL_INCLUDE_DIRS}  )
# link_libraries用来链接静态库,target_link_libraries用来链接导入库
LINK_LIBRARIES( ${PCL_LIBRARY_DIRS} )# 增加一个可执行的二进制
ADD_EXECUTABLE( generate_pointcloud generatePointCloud.cpp )TARGET_LINK_LIBRARIES( generate_pointcloud ${OpenCV_LIBS} ${PCL_LIBRARIES} )
# 可以在find_package()前设定_DIR,指向包含Config.cmake或-config.cmake的目录。
# _ROOT先设定,再设定_DIR,最后find_package();并且两个都能找到包,则_DIR起作用
set(OpenCV_ROOT "/home/nio/3rdparty/opencv-4.4.0/build")
set(OpenCV_DIR "/home/nio/3rdparty/opencv-4.4.0/build")# 查找PCL库(查找依赖包)
# find_package(<PackageName> [version] [EXACT] [QUIET] [MODULE]
# version和EXACT: 都是可选的,version指定的是版本,如果指定就必须检查找到的包的版本是否和version兼容。如果指定EXACT则表示必须完全匹配的版本而不是兼容版本就可以。
# QUIET 可选字段,表示如果查找失败,不会在屏幕进行输出(但是如果指定了REQUIRED字段,则QUIET无效,仍然会输出查找失败提示语)
# MODULE 可选字段。前面提到说“如果Module模式查找失败则回退到Config模式进行查找”,但是假如设定了MODULE选项,那么就只在Module模式查找,如果Module模式下查找失败并不回落到Config模式查找。
# REQUIRED可选字段。表示一定要找到包,找不到的话就立即停掉整个cmake。而如果不指定REQUIRED则cmake会继续执行。
FIND_PACKAGE( PCL REQUIRED COMPONENTS common io )# find_package()会把一整个依赖包的头文件包含路径、库路径、库名字、版本号等情况都获取到
# message 输出信息
message(STATUS "OpenCV library status:")
message(STATUS "    version: ${OpenCV_VERSION}")
message(STATUS "    libraries: ${OpenCV_LIBS}")
message(STATUS "    include path: ${OpenCV_INCLUDE_DIRS}")# 增加opencv的依赖
FIND_PACKAGE( OpenCV REQUIRED )# 添加头文件和库文件
# add_definitions()
ADD_DEFINITIONS( ${PCL_DEFINITIONS} )
INCLUDE_DIRECTORIES( ${PCL_INCLUDE_DIRS}  )
LINK_LIBRARIES( ${PCL_LIBRARY_DIRS} )ADD_EXECUTABLE( test2 test2.cpp )
TARGET_LINK_LIBRARIES( test2${OpenCV_LIBS}${PCL_LIBRARIES} )

将 .cpp文件 编译成一个库,供其他文件调用:

ADD_LIBRARY( slambase slamBase.cpp )
TARGET_LINK_LIBRARIES( slambase${OpenCV_LIBS} ${PCL_LIBRARIES} )
add_library(<name> [STATIC | SHARED | MODULE]   [EXCLUDE_FROM_ALL] source1 [source2 ...])
  • <name> :库的名字,直接写名字即可,不要写lib,会自动加上前缀的哈。

  • [STATIC | SHARED | MODULE] :
    SHARED: 动态库
    STATIC: 静态库
    MODULE: 在使用 dyld 的系统有效,如果不支持 dyld,则被当作 SHARED 对待。

  • EXCLUDE_FROM_ALL:这个库不会被默认构建,除非有其他的组件依赖或者手
    工构建。

变量名

PROJECT_SOURCE_DIR : 使用cmake命令后紧跟的目标,一般是工程的根目录
PROJECT_BINARY_DIR : 执行cmake命令的目录,通常是${PROJECT_SOURCE_DIR}/build
CMAKE_INCLUDE_PATH : 系统环境变量,非cmake变量
CMAKE_LIBRARY_PATH:系统环境变量,非cmake变量
CMAKE_CURRENT_SOURCE_DIR:当前处理的CMakeLists.txt所在的路径
CMAKE_CURRENT_BINARY_DIR:target编译目录(使用ADD_SURDIRECTORY(src bin)可以更改此变量的值 ,SET(EXECUTABLE_OUTPUT_PATH <新路径>)并不会对此变量有影响,只是改变了最终目标文件的存储路径)
CMAKE_CURRENT_LIST_FILE:输出调用这个变量的CMakeLists.txt的完整路径
CMAKE_CURRENT_LIST_LINE:输出这个变量所在的行
CMAKE_MODULE_PATH:定义自己的cmake模块所在的路径(这个变量用于定义自己的cmake模块所在的路径,如果你的工程比较复杂,有可能自己编写一些cmake模块,比如SET(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake),然后可以用INCLUDE命令来调用自己的模块)
EXECUTABLE_OUTPUT_PATH:重新定义目标二进制可执行文件的存放位置
LIBRARY_OUTPUT_PATH:重新定义目标链接库文件的存放位置
PROJECT_NAME:返回通过PROJECT指令定义的项目名称CMAKE_ALLOW_LOOSE_LOOP_CONSTRUCTS:用来控制IF ELSE语句的书写方式
CMAKE_MAJOR_VERSION:make主版本号,如3.4.1中3
CMAKE_MINOR_VERSION:cmake次版本号,如3.4.1中的4
CMAKE_PATCH_VERSION:cmake补丁等级,如3.4.1中的1
CMAKE_SYSTEM:操作系统名称,包括版本名,如Linux-2.6.22
CAMKE_SYSTEM_NAME:操作系统名称,不包括版本名,如Linux
CMAKE_SYSTEM_VERSION:操作系统版本号,如2.6.22
CMAKE_SYSTEM_PROCESSOR:电脑处理器名称,如i686
UNIX:在所有的类UNIX平台为TRUE,包括OS X和cygwin,Linux/Unix操作系统
WIN32:在所有的win32平台为TRUE,包括cygwin,Windows操作系统
APPLE:苹果操作系统;

ORB-SLAM2的例子

cmake_minimum_required(VERSION 2.8)      # 设定cmake最小版本号
project(ORB_SLAM2)                      # 指定项目工程IF(NOT CMAKE_BUILD_TYPE)                # CMAKE_BUILD_TYP: CMAKE 编译的类型(debug;release)SET(CMAKE_BUILD_TYPE Release)           # IF 和 ENDIF构成一个if语句
ENDIF()MESSAGE("Build type: " ${CMAKE_BUILD_TYPE})        # 输出消息:"Build type: Release"(打印调试信息)# ${XXX} : 变量XXX的值# cmake_c_flags用来设置编译选项 如 -g -wall(不展示警告)    ;-march=native,GCC会自动检测你的CPU支持的指令集
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}  -Wall  -O3 -march=native ")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall   -O3 -march=native")# Check C++11 or C++0x support
include(CheckCXXCompilerFlag)                   # include:从文件或模块加载并运行CMake代码 ;# CheckCXXCompilerFlag: 检查CXX编译器是否支持给定标志# 以下代码都用于自动判断系统编译器是否支持c++11标准;
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")add_definitions(-DCOMPILEDWITHC11)message(STATUS "Using flag -std=c++11.")
elseif(COMPILER_SUPPORTS_CXX0X)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")add_definitions(-DCOMPILEDWITHC0X)message(STATUS "Using flag -std=c++0x.")
else()message(FATAL_ERROR "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()LIST(APPEND CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake_modules)
# list(APPEND <list><element> [<element> ...])  添加新element到list中
# CMAKE_MODULE_PATH:  指定要由CMake模块加载的CMake模块的搜索路径include() 要么 find_package()命令,然后检查CMake随附的默认模块。
# {PROJECT_SOURCE_DIR}为包含PROJECT()的最近一个CMakeLists.txt文件所在的文件夹
# cmake_modules:用于找寻不知名库时,事先在CMakeLists.txt相同位置建立一个叫cmake_modules的文件夹,在里面创建寻找库并命名的指令                             set(OpenCV_DIR /home/z/cmake-3.4.9/build)       # 设置OpenCV的目录
find_package(OpenCV 3.4.9 QUIET)
if(NOT OpenCV_FOUND)message(FATAL_ERROR "OpenCV > 2.4.3 not found.")endif()find_package(Eigen3 3.1.0 REQUIRED)             # 找到各种头文件以及源码
find_package(Pangolin REQUIRED)include_directories(
# 提供头文件路径它提供了一个搜索头文件暂时的根目录,即你可以在cmakelists中写上
# include_directories(/usr/local/include)来让库文件搜索以/usr/local/include为基础,即在main函数前写上#include “opencv/cv.h"即可  ${PROJECT_SOURCE_DIR}                           # {PROJECT_SOURCE_DIR}为包含PROJECT()的最近一个CMakeLists.txt文件所在的文件夹
${PROJECT_SOURCE_DIR}/include
${EIGEN3_INCLUDE_DIR}
${Pangolin_INCLUDE_DIRS}
)set(CMAKE_LIBRARY_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/lib)
#设置变量到工程lib下    构建时将所有LIBRARY目标放置的位置add_library(${PROJECT_NAME} SHARED              # 建立共享库
src/System.cc
src/Tracking.cc
src/LocalMapping.cc
src/LoopClosing.cc
src/ORBextractor.cc
src/ORBmatcher.cc
src/FrameDrawer.cc
src/Converter.cc
src/MapPoint.cc
src/KeyFrame.cc
src/Map.cc
src/MapDrawer.cc
src/Optimizer.cc
src/PnPsolver.cc
src/Frame.cc
src/KeyFrameDatabase.cc
src/Sim3Solver.cc
src/Initializer.cc
src/Viewer.cc
)target_link_libraries(${PROJECT_NAME}        # 该指令的作用为将目标文件与库文件进行链接
${OpenCV_LIBS}
${EIGEN3_LIBS}
${Pangolin_LIBRARIES}
${PROJECT_SOURCE_DIR}/Thirdparty/DBoW2/lib/libDBoW2.so
${PROJECT_SOURCE_DIR}/Thirdparty/g2o/lib/libg2o.so
)# Build examplesset(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/RGB-D)
# 指定可执行文件的输出位置  CMAKE_RUNTIME_OUTPUT_DIRECTORY: 构建RUNTIME目标文件的输出目录add_executable(rgbd_tum                         # 使用指定的源文件将可执行文件添加到项目中。
Examples/RGB-D/rgbd_tum.cc)
target_link_libraries(rgbd_tum ${PROJECT_NAME})set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/Stereo)add_executable(stereo_kitti
Examples/Stereo/stereo_kitti.cc)
target_link_libraries(stereo_kitti ${PROJECT_NAME})add_executable(stereo_euroc
Examples/Stereo/stereo_euroc.cc)
target_link_libraries(stereo_euroc ${PROJECT_NAME})     set(CMAKE_RUNTIME_OUTPUT_DIRECTORY ${PROJECT_SOURCE_DIR}/Examples/Monocular)add_executable(mono_tum
Examples/Monocular/mono_tum.cc)
target_link_libraries(mono_tum ${PROJECT_NAME})add_executable(mono_kitti
Examples/Monocular/mono_kitti.cc)
target_link_libraries(mono_kitti ${PROJECT_NAME})add_executable(mono_euroc
Examples/Monocular/mono_euroc.cc)
target_link_libraries(mono_euroc ${PROJECT_NAME})

补充

list

list (subcommand <list> [args...])
  • subcommand为具体的列表操作子命令,例如读取、查找、修改、排序等。
  • <list>为待操作的列表变量
  • [args…]为对列表变量操作需要使用的参数表,不同的子命令对应的参数也不一致。

自动检测编译器是否支持C++11

include(CheckCXXCompilerFlag)
CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
CHECK_CXX_COMPILER_FLAG("-std=c++0x" COMPILER_SUPPORTS_CXX0X)
if(COMPILER_SUPPORTS_CXX11)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
elseif(COMPILER_SUPPORTS_CXX0X)set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++0x")
else()message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
endif()

警告:检测到时钟错误。您的创建可能是不完整的。

在项目根目录下执行命令:

touch *

更新所有文件时间。

CMakeLists入门相关推荐

  1. gcc编译可执行文件和cmake编译可执行文件

    gcc编译 gcc的下载(下载mingw,里面包含gcc) 下载安装MinGW-w64详细步骤(c/c++的编译器gcc的windows版,win10真实可用) gcc编译可执行文件 由源码转换为可执 ...

  2. CMakeLists.txt从入门到精通

    文章目录 前言 一 一般工程开头的一些设置案例 二 动态库与静态库的生成 2.1 动态库 2.2 静态库 三 优化选项的设置 四 生成库时的设置 五 常见依赖库的调用 5.1 OpenCV库 六 设置 ...

  3. ESP32-C3入门教程 环境篇⑥——ESP-IDF编译原理简述(CMakeLists/CMake)和构建自定义项目

    文章目录 一.前言 二.ESP-IDF编译原理 2.1 基础知识 2.2 软件组件 2.3 构建过程 2.4 最简单的示例项目 三.构建自定义项目 3.1 项目重命名 3.2 main.c重命名 3. ...

  4. ++项目 cmake头文件路径_CMAKE入门实战

    0.导语 最近做的项目使用CLION构建,而这个采用CMakeLists.txt管理,因此为了更好的学习,故找到了一篇大牛级别的入门文章,有文章有代码,本文是花了一点时间把这篇文章学习后的重要点记录吧 ...

  5. CMakeLists

    CMake是跨平台编译工具,比make更高级一些.其编译的主要工作是生成CMakeLists.txt文件,然后根据该文件生成Makefile,最后调用make来生成可执行程序或者动态库.所以基本步骤就 ...

  6. gazebo入门_【ROS-Gazebo】仿真插件编写教程(1)——概述

    前言 本系列教程的主要是对 Gazebo的官网教程 的翻译与理解.之前查找国内的中文资料,发现并没有关于如何编写Gazebo插件的教程.据我猜测,大概是因为这个技能属于"两不管"地 ...

  7. 一文详解CMakeLists文件编写语法规则详解

    作者丨zhanghm1995@blog 来源丨https://blog.csdn.net/zhanghm1995/article/details/80902807 编辑丨3D视觉工坊 基本语法规则 C ...

  8. 七夕福利 | 3D视觉从入门到精通系统学习教程

    写在前面 首先提前祝大家七夕快乐,感谢大家对工坊的陪伴与支持! 今天是七夕福利活动的最后一天,共100张券,已经送出去了60多张,还剩不到35张,大家可以抓住本次的活动机会,享受全年的最低价(优惠了7 ...

  9. 智能车技术与实践_ROS入门

    智能车技术与实践--ROS入门 前言:本次作业旨在通过不同的任务使同学掌握ROS基础,包括工作环境.功能包的创建. 预先要求:ubuntu18.04 + ROS melodic 任务一:创建ROS工作 ...

最新文章

  1. Netty3 源代码分析 - NIO server绑定过程分析
  2. python打开后的界面-Python - tkinter:打开和关闭对话框窗口
  3. 30分钟Git命令 从入门到放弃
  4. Ubuntu下搭建sun-jdk和Maven2
  5. [BUUCTF-pwn]——[ZJCTF 2019]EasyHeap
  6. 电子商务实战课程-张晨光-专题视频课程
  7. html5 canvas 版 hello world! 暨haXe简介
  8. Springcloud 高效率本地加Redis双级缓存
  9. .net socket与完成端口、异步发送相关研究
  10. 带有记忆的菲波那切数列
  11. 100w条数据插入Mysql 数据库,耗时仅10s
  12. SSIS高级转换任务—导出列
  13. VFIO PassThrough
  14. 巴塞罗那2019-20赛季球队大名单
  15. Android中获取系统所认为的最小滑动距离TouchSlop
  16. 【教你如何用驱动人生解决驱动问题】
  17. 叠片过滤器:全自动叠片盘式过滤器介绍
  18. Pycurl的简单使用与对比
  19. 【Rust日报】2020-10-02 移动操作系统SailfishOS支持Rust了
  20. 【20210727】图说全球网站数量及服务器市场份额

热门文章

  1. juju创建lxd容器时如何使用本地镜像(by quqi99)
  2. VMWare虚拟机非正常关闭后无法启动的解决方案
  3. javascript精雕细琢(四):认亲大戏——通过console.log彻底搞清this
  4. facebook注册脚本
  5. nginx服务器网站文件存放处,Nginx服务器安装部署
  6. css制作提示小图标(内容撑开盒子)
  7. B站笔试真题之[编程题]简单表达式计算
  8. Jenkins更换插件下载源(清华源)
  9. Welcome To My “Hello World“
  10. MegEngine Windows Python wheel 包减肥之路