cmake
1.“~” 表示主目录,也就是当前登录用户的用户目录
比如用户是“zheng”,则mac电脑的用户目录就是/users/zheng;
2.“/”是指根目录,所有目录最顶层的目录;
3.“./”表示当前目录,一般和其他文件夹或者文件结合使用,指当前目录下的东西.
CMake Reference Documentation — CMake 3.28.0-rc2 Documentation
这个是官方文档,英语好的,已经有基础的可以直接看这个
Linux下CMake简明教程_爱就是恒久忍耐的博客-CSDN博客_cmake
CMake教程(常见变量)_project_source_dir_开始沸腾了的博客-CSDN博客
CMakeLists:在catkin_make期间生成文件,如xxxConfig.Cmake导出本包的资源 加入到catkin_INCLUDE_DIRS和catkin_LIBRARIES,find_package本包依赖所需依赖(包含依赖包并不会递归其依赖的子包为依赖,因为CMakeLists是独立的)。
Package.xml:是了解一个包的所有入口,依赖项可以用来解决包之间的编译和执行顺序,包含某个包会自动递归其所依赖的子包作为依赖。
因此在Package.xml声明依赖(包间依赖关系)和CMakeLists中find_package(包所需依赖)都要有,否则前者导致编译顺序出错,后者导致无头文件目标文件链接失败。
CMakeLists.txt是cmake编译框架下的文件,而catkin是cmake加入了一些宏命令来适配ROS(个人理解)。因此在CMakeLists中写入catkin支持的宏如catkin_package add_service_files generate_messages等会自动帮你生成一些文件
package.xml才是ROS包的命根子,无论是rospack rosrun,catkin_make等ros中用的命令,甚至是roslaucnh 中的$(find package)都是通过搜索ros_path下的所有文件夹中的package.xml的。然后通过该文件来获取程序包信息。
流程
main
库的头文件导入
生成可执行文件
库的可执行文件链接
头文件导入
库文件
生成动态链接库(.c)
头文件导入(.h)
文件夹命名规则
build
cmake的地方
lib
编译生成的库文件存放处
bin
二进制文件存放的地方,也就是可执行文件
常用命令
set
Cmake入门之——Set方法(六)_cmake cache string_PGzxc的博客-CSDN博客
用来将一些文件 和一个自定义名称绑定
1 | set(OpenCV_DIR /home/xing/opencv-4.5.3/build) |
用于简洁代码作用和aux_source_directory一样
aux_source_directory(dir var)
第一个参数dir是指定目录,第二个参数var是用于存放源文件列表的变量。
1 | cmake_minimum_required (VERSION 2.8) |
install
cmake使用教(二) install的使用_cmakelist install-CSDN博客
用于配置安装路径
1 | INSTALL(TARGETS myrun mylib mystaticlib |
上面的例子会将:
可执行二进制myrun 安装到${CMAKE_INSTALL_PREFIX}/bin 目录
动态库libmylib安装到${CMAKE_INSTALL_PREFIX}/lib目录
静态库libmystaticlib 安装到${CMAKE_INSTALL_PREFIX}/libstatic目录
特别注意的是你不需要关心TARGETS具体生成的路径,只需要写上TARGETS名称就可以
了。
要写成相对路径,即不要以/开头
如果不填数据类型就默认是二进制
指定安装路径
include_directories
作用的target_include_library类似,官方推荐使用后者。
这个相对target_include_library的区别在于这个是直接给这个工程提供头文件路径,而include_directories是给具体的目标添加头文件,比如已经生成的库文件
该命令是用来向工程添加多个指定头文件的搜索路径,路径之间用空格分隔。
1 | cmake_minimum_required (VERSION 2.8) |
add_executable
使用指定的源文件创建出一个可执行文件
CMake系列讲解(入门篇)1.4 基础命令CMake-add_executable()_在下马农的博客-CSDN博客_cmake add_ex
1 | cmake_minimum_required (VERSION 2.8) |
add_subdirectory
作用是添加编译子目录
add_subdirectory(source_dir [binary_dir] [EXCLUDE_FROM_ALL])
一共有三个参数,后两个是可选参数.
source_dir 源代码目录
指定一个包含CMakeLists.txt和代码文件所在的目录,该目录可以是绝对路径,也可以是相对路径,对于后者相对路径的起点是CMAKE_CURRENT_SOURCE_DIR。此外,如果子目录再次包含的CMakeLists.txt,则将继续处理里层的CMakeLists.txt,而不是继续处理当前源代码。
binary_dir 二进制代码目录
这个目录是可选的,如果指定,cmake命令执行后的输出文件将会存放在此处,若没有指定,默认情况等于source_dir没有进行相对路径计算前的路径,也就是CMAKE_BINARY_DIR。
EXCLUDE_FROM_ALL标记
这个标志是可选的,如果传递了该参数表示新增加的子目录将会排除在ALL目录之外(可能是make系统中的make all?),表示这个目录将从IDE的工程中排除。用户必须显式在子文件这个编译目标(手动cmake之类的)。指定了这个文件夹,表示这个文件夹是独立于源工程的,这些函数是有用但是不是必要的,比如说我们一系列的例子。

1 | cmake_minimum_required (VERSION 2.8) |
1 | aux_source_directory (. SRC_LIST) |
find_package
作用:
他主要是寻找.cmake文件。根据.cmake生成对应的头文件目录和库文件路径。
我看了几个.cmake文件。里面有对于路径的定义 比如OpenCV_INCLUDE_DIRS
不管哪种方式安装的库文件,如果我们需要自己的项目中使用这些库,首先面临的第一个问题就是如何找到这些库。所谓“找到”这些库,其实是根据我们的需要找到指定版本的库头文件包含路径、链接库路径等,从而能够满足我们开发项目的编译链接需要。
是用于查找当前功能包所依赖的包
1 | find_package(catkin REQUIRED COMPONENTS |
1 | set(CMAKE_CXX_COMPILER /usr/bin/g++) |
1 | set(OpenCV_INCLUDE_DIRS "") |
从这些路径之后可以直接找到动态库或者静态库的位置。之后执行target_link_libraries
有两种配置方式。一种是set,一种是list
他会到这两个配置方式指定的路径下进行搜索
如果没有配置set list
他会直接从默认路径中进行寻找默认路径
find_library

1 | cmake_minimum_required (VERSION 3.5) |
在指定目录下查找指定库,并把库的绝对路径存放到变量里,其第一个参数是变量名称,第二个参数是库名称,第三个参数是HINTS,第4个参数是路径,其它用法可以参考cmake文档
add_library
生成对象库(也就是.so或者.a文件)
windows下就是dll和lib文件
1 | add_library(hello hello.cpp) |
target_include_directories
往可执行文件或生成的库中添加头文件目录
1 | cmake_minimum_required (VERSION 3.12.1) |
target_link_directories
这个和下面target_link_libraries的区别在于
target_link_directories是链接库的目录
target_link_libraries是链接库
1 | target_link_directories(mytarget PUBLIC /path/to/mylib) |
link_library
历史遗留物
也是用来将main可执行文件与动态库进行链接的,不过由于无法明确链接的是谁,所以目前cmake官方不推荐使用
target_link_libraries
指定链接给定目标和/或其依赖项时要使用的库。命名的 <font style="color:rgb(77, 77, 77);"><tartget></font> 必须是由<font style="color:rgb(77, 77, 77);">add_executable()</font>或add_library()之类的命令创建的。一般与 link_directories连用(添加外部库的搜索路径 )
链接对象库到可执行文件(一般是这样的)
1 | ## Specify libraries to link a library or executable target against |
1 | cmake_minimum_required (VERSION 3.12.1) |
target_complie_options
给对象库添加编译选项
1 | target_compile_options(hello PUBLIC -Wall) |
add_compile_option
这个是用来添加编译选项的
1 | cmake_minimum_required (VERSION 2.8) |
option
类似添加宏定义,用于条件编译,就是满足条件才编译这个文件,甚至可以直接控制程序的输出(这里功能和宏定义相同)
1 | cmake_minimum_required(VERSION 3.5) |
这里使用了option命令,其第一个参数是这个option的名字,第二个参数是字符串,用来描述这个option是来干嘛的,第三个是option的值,ON或OFF,也可以不写,不写就是默认OFF。
然后编写src目录下的CMakeLists.txt,如下:
1 | cmake_minimum_required (VERSION 3.5) |
<font style="color:rgb(77, 77, 77);">cmake … -DMYDEBUG=ON</font>这条命令可以直接往设定的宏输入数据
add_definitions
这个主要使用修改输出的宏名称,保留原来名称,这里更像是取个别名
1 | cmake_minimum_required(VERSION 3.5) |
1 | #include <stdio.h> |
ros相关命令
add_service_files(这一步区别于话题通信,其用的是add_message_files指定msg文件
将创建的src文件夹加入,目的是使其在srv目录下寻找srv文件
1 | add_service_files( |
generate_messages
指定生成消息文件时的依赖项
srv文件中利用到了标准数据,所以需要std_msgs
1 | generate_messages( |
catkin_package
声明依赖的包的依赖
CATKIN_DEPENDS 选项和 DEPENDS 选项十分相似,但是你只能在其列表中放置 catkin 程序包。将 catkin 依赖设置为一个单独的选项的好处是可以让 catkin 执行一些额外的检查,然后警告你有什么不妥的做法。
catkin_package是给下游(使用该包的包)使用的,它用于向其他包导出依赖,这些依赖可能是本包给其他包提供的公共头文件、库,或者是本包依赖的其他包。
1 | ## The catkin_package macro generates cmake config files for your package |
DEPENDS 和 CATKIN_DEPENDS 用来告诉 catkin 需要将你程序包的哪些依赖项,传递给使用 find_package(…) 查找你的程序包的程序包。
CATKIN_DEPENDS 选项和 DEPENDS 选项十分相似,但是你只能在其列表中放置 catkin 程序包。将 catkin 依赖设置为一个单独的选项的好处是可以让 catkin 执行一些额外的检查,然后警告你有什么不妥的做法。
是当前功能包所依赖的包所依赖的包
1 | #执行时依赖 |
add_dependencies
保证编译的文件逻辑问题不出错,举例:让自定义文件先运行,源文件后编译
- 添加add_dependencies(res myMath),意思就是告诉编译器,我知道生成res程序要链接myMath这个库文件,但是现在我还没有这个库文件,你先生成res,我随后就把库文件myMath给你生成出来。
1 | #指定cmake最低版本 |
预定义变量
catkin_LIBRARIES
catkin的基础库
如果cpp中用到第三方插件,需要在这里进行target_link 链接到第三方库文件,现在链接的库是catkin的基础库
1 | target_link_libraries(talker ${catkin_LIBRARIES} ) |
project_name
也就是功能包的名字
project的名字


EXECUTABLE_OUTPUT_PATH
目标二进制可执行文件的存放位置
1 | aux_source_directory (. SRC_LIST) |
常用操作
编译单个文件
VSCode编译单文件及多文件方法(基于g++,cmake,json三种方法)_vscode 多文件编译_DogDog_Shuai的博客-CSDN博客
一.改cmakelisets.txt
1 | project(MYSWAP)//起一个项目名 |
这个意思就是生成可执行文件只参考一个文件
二.改task.json
系统自动生成的task文件默认是单文件调试,所以可以修改task.json的args部分,修改后
1 | { |
概念辨析
catktin_make和cmake的区别
https://www.cnblogs.com/Jessica-jie/p/6706513.html
caktin_make 就是将cmake 和make命令进行了封装
cmak 不会找package.xml文件, 但catkin需要. 依据cmakelists.txt文件编译需要清晰指出头文件和库文件的指向.
catkin_make编译指定的包
1 | $ catkin_make -DCATKIN_WHITELIST_PACKAGES="package1;package2" |
恢复编译所有的包
1 | $ catkin_make -DCATKIN_WHITELIST_PACKAGES="" |
catkin_make和catkin build 的区别
catkin build的行为类似于并行版本的catkin_make_isolatied
catkin build 就是会将pkg独立编译,而catkin_make 不会
相比catkin_make的一个改进是将工作空间下的所有的pkg进行独立编译,缺点就是编译时间比catkin_make更长。
make install
make&& make install的意思_make && make install-CSDN博客
make是编译的意思。就是把源码包编译成二进制可执行文件,make去找Makefile
make install 就是安装的意思。它也从Makefile中读取指令,然后安装到指定的位置。
源码包的安装分成一下几个过程:
- Tar:解压这个源码软件包。
- Cd:进入到这个源码包。
- ./configure:“configure”会在你的系统上测试存在的特性(或者bug!)然后来建立Makefile文件来完成make!
- Make:编译程序。
- Make install:安装文件!
make&& make install的意思是:
make与makeinstall是两个命令,在你./configuration生成了Makefile之后执行编译安装;
(这里的./configuration用来生成makefile,这是个脚本文件,有cmake)
与&&一起的还有||,不过意思不一样,&&是与,||是或;
make && makeinstall的意思就是执行make如果没有发生错误就执行make install