cmake到ROS的catkin_make的CMakeLists.txt文件有什么区别和联系 - 教程
这是一个非常核心且重要的问题,尤其对于从通用 C++ 开发转向 ROS (Robot Operating System) 开发的工程师来说。
简单来说,它们的关系是:继承与扩展。
一个用于 catkin_make 的 CMakeLists.txt 文件 本质上就是一个标准的 CMakeLists.txt 文件,但它额外使用了一套由 Catkin 提供的、为 ROS 定制的宏和变量。Catkin 并没有取代 CMake,而是基于 CMake 构建了一套工作流和规范,专门用于管理 ROS 软件包(Package)之间的复杂依赖关系。
下面我们来详细对比它们的联系和区别。
联系:共同的基础
所有在标准 CMakeLists.txt 中能用的命令,在 Catkin 的 CMakeLists.txt 中也完全适用。这包括:
- 核心逻辑:
if(),else(),foreach(),list()等控制流命令完全一样。 - 设置变量:
set(VARIABLE "value")的用法完全一样。 - 添加目标:
add_executable(my_node src/my_node.cpp)(创建可执行文件)add_library(my_lib src/my_lib.cpp)(创建库)
- 链接库:
target_link_libraries(my_node my_lib)(链接目标)
- 包含头文件:
target_include_directories(my_node PUBLIC include)
核心思想:catkin_make 只是一个封装工具,它最终还是会调用 cmake 和 make。所以,你所知道的 CMake 知识是构建 Catkin 项目的基石。
区别:Catkin 引入的 ROS 特有扩展
Catkin 的主要目的是为了解决 ROS 的核心需求:管理大量独立开发、又相互依赖的软件包。为此,它引入了一系列特殊的命令和变量。
1. 项目声明与包信息 (catkin_package)
这是最核心、最重要的区别。
标准 CMake:
project(my_awesome_project)project()声明了项目名称,并设置了一些项目级别的变量。Catkin (ROS):
project(my_ros_package) ... # 这是 Catkin 的核心命令! catkin_package( INCLUDE_DIRS include LIBRARIES ${PROJECT_NAME} CATKIN_DEPENDS roscpp std_msgs DEPENDS system_lib )catkin_package()的作用远超project()。它向 ROS 构建系统声明:- 这是一个 Catkin 软件包。
- 它向其他软件包“导出”了什么信息。比如:
INCLUDE_DIRS: 当其他包依赖此包时,需要包含的头文件目录。LIBRARIES: 当其他包依赖此包时,需要链接的库。CATKIN_DEPENDS: 依赖的其他 Catkin 软件包(如roscpp)。DEPENDS: 依赖的系统库(如Boost,Eigen)。
一句话总结:
project()是对内的声明,而catkin_package()是对外的接口声明,它定义了这个包如何被其他 ROS 包所使用。
2. 查找依赖 (find_package)
标准 CMake:
find_package(Boost 1.65.1 REQUIRED)直接查找系统或指定路径下的库。
Catkin (ROS):
find_package(catkin REQUIRED COMPONENTS roscpp std_msgs sensor_msgs tf )这里
find_package的用法被 Catkin "重载"了。- 你总是先查找
catkin这个“元包”(meta-package)。 COMPONENTS关键字后面列出所有你需要的其他 ROS 软件包。- Catkin 会自动帮你找到这些组件,并创建好相关的变量,如
${catkin_INCLUDE_DIRS}和${catkin_LIBRARIES},供你后续使用。
- 你总是先查找
3. ROS 消息/服务/动作的自动生成
这是 ROS 独有的功能,标准 CMake 完全没有这个概念。
标准 CMake: N/A
Catkin (ROS):
# 1. 找到生成消息所需要的依赖 find_package(catkin REQUIRED COMPONENTS message_generation std_msgs) # 2. 列出你的 .msg 和 .srv 文件 add_message_files(FILES MyMessage.msg) add_service_files(FILES MyService.srv) # 3. 核心命令:调用它来生成 C++, Python 等语言的头文件和代码 generate_messages(DEPENDENCIES std_msgs)这套流程会自动处理
.msg文件,在构建目录中生成对应的MyMessage.h头文件,并确保依赖它的目标在头文件生成之后才开始编译。
4. 安装 (install)
标准 CMake:
install(TARGETS my_app DESTINATION bin) install(FILES my_header.h DESTINATION include)路径是用户通过
CMAKE_INSTALL_PREFIX自定义的。Catkin (ROS):
# 使用 Catkin 提供的变量来确保安装到 ROS 标准目录结构中 install(TARGETS my_node RUNTIME DESTINATION ${CATKIN_PACKAGE_BIN_DESTINATION} ) install(DIRECTORY launch/ DESTINATION ${CATKIN_PACKAGE_SHARE_DESTINATION}/launch )Catkin 提供了一系列
CATKIN_PACKAGE_*_DESTINATION变量,确保你的可执行文件、库、launch 文件、配置文件等能被安装到 ROS 环境下的标准位置(如/opt/ros/noetic/lib/<package_name>),这样rosrun和roslaunch才能找到它们。
示例:并排对比
假设我们要创建一个简单的可执行文件。
| 标准 CMakeLists.txt | Catkin (ROS) CMakeLists.txt |
|---|---|
|
设置 C++ 标准
set(CMAKE_CXX_STANDARD 14)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
查找系统库 (例如 Boost)
find_package(Boost REQUIRED)
include_directories(${Boost_INCLUDE_DIRS})
创建可执行文件
add_executable(my_app src/main.cpp)
链接库
target_link_libraries(my_app
PRIVATE
${Boost_LIBRARIES}
)
安装
install(TARGETS my_app
DESTINATION bin)
cmake_minimum_required(VERSION 3.0.2)
project(my_ros_package)查找 Catkin 依赖 (roscpp, std_msgs)
find_package(catkin REQUIRED COMPONENTS
roscpp
std_msgs
)
Catkin 核心:声明包的导出信息
catkin_package(
INCLUDE_DIRS
LIBRARIES
CATKIN_DEPENDS roscpp std_msgs
DEPENDS
)
包含 Catkin 找到的头文件路径
include_directories(
${catkin_INCLUDE_DIRS}
)
创建 ROS 节点 (可执行文件)
add_executable(my_node src/my_node.cpp)
链接 Catkin 找到的库
target_link_libraries(my_node
${catkin_LIBRARIES}
)
安装规则 (通常在 ROS 中是可选的)
install(…)
总结
| 特性 | 标准 CMake | Catkin (ROS) CMake |
|---|---|---|
| 基础语法 | 是基础 | 完全继承和使用 |
| 项目声明 | project(name) | project(name) + catkin_package() (核心) |
| 查找依赖 | find_package(Lib) | find_package(catkin COMPONENTS ...) |
| 代码生成 | 不处理特定领域文件 | generate_messages() 等用于 .msg/.srv/.action |
| 构建工具 | cmake & make | catkin_make (封装了 cmake & make) |
| 目标 | 构建通用的软件 | 构建能在 ROS 生态中互相发现和通信的软件包 |
把 Catkin 看作是 CMake 的一个**“行业特定框架”**,就像 Ruby on Rails 是 Ruby 的 Web 开发框架一样。你仍然在写 CMake 代码,但你需要遵循 Catkin 的规则并使用它提供的工具,才能让你的软件包无缝地融入整个 ROS 系统。

浙公网安备 33010602011771号