CMake、Ament 与 Catkin:ROS 构建系统的前世今生

CMake、Ament 与 Catkin:ROS 构建系统的前世今生

如果你开发过 ROS(机器人操作系统)程序,一定对 CMakeLists.txtpackage.xml 以及 catkin_makecolcon build 这些名词不陌生。但你真的清楚 CMakeAment (ROS 2)和 Catkin(ROS 1)之间的关系吗?它们有什么区别?为什么 ROS 2 要从 Catkin 迁移到 Ament?

本文将为你彻底讲清这三者的定位、联系与区别,帮助你更好地理解 ROS 的构建体系。

一、CMake:通用的构建引擎

CMake 是一个跨平台的开源构建系统生成器。它本身不直接编译代码,而是根据 CMakeLists.txt 生成原生构建工具(如 Makefile、Ninja、Visual Studio 工程)所需的文件,再由这些工具完成实际的编译链接。

CMake 的核心能力

  • 检测编译器和系统环境
  • 查找依赖库、头文件(find_packagefind_library
  • 定义构建目标(可执行文件、静态/动态库)
  • 管理编译选项、链接选项
  • 支持测试(CTest)、打包(CPack)

适用范围

任何 C/C++ 项目(也支持 Fortran、CUDA 等),以及需要复杂构建配置的 Python 项目(通过 pybind11 等)。CMake 不包含任何机器人领域的概念

典型用法

bash 复制代码
mkdir build && cd build
cmake ..      # 生成 Makefile
make          # 实际编译

二、Catkin:ROS 1 的元构建系统

Catkin 是 ROS 1 官方采用的构建系统,它构建在 CMake 之上,为 ROS 1 包提供了额外的抽象和约定。

Catkin 解决了什么问题?

  • 需要从 .msg / .srv 文件自动生成代码
  • 多个 ROS 包之间复杂的依赖关系
  • 工作空间(workspace)环境变量自动设置(setup.bash

Catkin 的组成

  • package.xml:包的元信息(名称、版本、依赖)
  • CMakeLists.txt:其中调用 find_package(catkin REQUIRED ...)catkin_package()
  • 构建工具:catkin_make(官方简单工具)或 catkin build(更强大的 catkin_tools

Catkin 典型用法

bash 复制代码
mkdir -p ~/catkin_ws/src
cd ~/catkin_ws
catkin_make                 # 一次性构建所有包
catkin_make --only-pkg-with-deps my_pkg   # 只构建某个包

Catkin 的 CMakeLists.txt 片段

cmake 复制代码
cmake_minimum_required(VERSION 2.8.3)
project(my_ros1_pkg)

find_package(catkin REQUIRED COMPONENTS roscpp std_msgs)

catkin_package(
  INCLUDE_DIRS include
  LIBRARIES ${PROJECT_NAME}
  CATKIN_DEPENDS roscpp std_msgs
)

add_executable(my_node src/my_node.cpp)
target_link_libraries(my_node ${catkin_LIBRARIES})

三、Ament:ROS 2 的元构建系统

Ament 是 ROS 2 中取代 Catkin 的元构建系统。同样基于 CMake,但设计上更加现代化、模块化。

Ament 相比 Catkin 的改进

  • 完全隔离的构建 :不再有 devel 空间,所有产物直接安装到 install 空间,避免交叉污染。
  • 一等 Python 支持 :提供 ament_python 构建类型,原生支持纯 Python 包。
  • 更清晰的依赖管理ament_target_dependencies 自动处理 include 路径、库、编译定义。
  • 更模块化ament_cmake 由多个小组件(ament_cmake_coreament_cmake_export_* 等)组成,按需使用。
  • 与 colcon 深度集成colcon build 统一构建 C++ 和 Python 包。

Ament 典型用法

bash 复制代码
mkdir -p ~/ros2_ws/src
cd ~/ros2_ws
colcon build                          # 构建所有包
colcon build --packages-select my_pkg # 只构建指定包

Ament 的 CMakeLists.txt 片段

cmake 复制代码
cmake_minimum_required(VERSION 3.8)
project(my_ros2_pkg)

find_package(ament_cmake REQUIRED)
find_package(rclcpp REQUIRED)
find_package(std_msgs REQUIRED)

ament_target_dependencies(my_node rclcpp std_msgs)

# 生成消息/服务(ROS 2 使用 rosidl)
rosidl_generate_interfaces(${PROJECT_NAME}
  "msg/MyMsg.msg"
  "srv/MySrv.srv"
)

ament_package()

四、三者关系一图以蔽之

text 复制代码
┌─────────────────────────────────────────────────────────┐
│                     CMake                               │
│               (通用构建系统生成器)                        │
│    提供:target, find_package, add_executable ...       │
└─────────────────┬───────────────────┬───────────────────┘
                  │                   │
                  ▼                   ▼
    ┌─────────────────────┐   ┌─────────────────────┐
    │      Catkin         │   │      Ament          │
    │   (ROS 1 元构建)     │   │   (ROS 2 元构建)     │
    │ 扩展:catkin_package │   │ 扩展:ament_* 宏     │
    │ 工具:catkin_make    │   │ 工具:colcon        │
    └─────────────────────┘   └─────────────────────┘
  • CMake 是"引擎",提供底层能力。
  • CatkinAment 是"专用车身套件",基于 CMake 封装出 ROS 领域的高级功能。

五、核心功能对比表

功能点 CMake Catkin (ROS 1) Ament (ROS 2)
适用领域 任何 C/C++ 项目 仅 ROS 1 包 仅 ROS 2 包
包清单文件 无(或自定义) package.xml package.xml
查找 ROS 依赖 不支持 find_package(catkin ...) find_package(rclcpp ...)
添加 ROS 依赖 手动 target_link... ${catkin_LIBRARIES} ament_target_dependencies
生成消息/服务代码 需要手写生成器 add_message_files + generate_messages rosidl_generate_interfaces
环境脚本 devel/setup.bash install/setup.bash
构建命令 cmake && make catkin_makecatkin build colcon build
构建空间隔离 手动控制 develbuild 混用 build + install 完全隔离

六、为什么 ROS 2 要从 Catkin 迁移到 Ament?

  1. 现代 CMake 需求 :Catkin 要求 CMake 2.8.3(2009 年标准),而 Ament 要求 3.8+,可利用现代 CMake 特性(如 target 粒度控制、INTERFACE 传播)。
  2. Python 包支持 :Catkin 对 Python 包的处理比较别扭(需要手动编写 setup.py),Ament 则原生支持 ament_python 构建类型。
  3. 隔离构建 :Catkin 的 devel 空间容易导致环境污染和难以复现的问题;Ament 强制安装到 install 空间,每个包独立。
  4. 模块化与可维护性 :Ament 拆分为多个独立的 CMake 子包(如 ament_cmake_export_dependencies),更易于扩展和维护。
  5. 与 colcon 统一体验 :无论 C++ 还是 Python 包,都用 colcon build 构建,开发者体验一致。

七、常见问题速查

Q1:我能在 ROS 2 中直接用 CMake 而不通过 Ament 吗?

技术上可以,但你会失去消息生成、环境脚本自动配置、依赖传播等 ROS 2 生态的关键功能。强烈不建议这么做。

Q2:Catkin 和 Ament 的 CMakeLists.txt 可以互相转换吗?

不能直接转换 ,但迁移思路是:将 catkin_package() 改为 ament_package(),将 find_package(catkin REQUIRED COMPONENTS ...) 拆成多个独立的 find_package,并替换依赖添加方式为 ament_target_dependencies

Q3:Colcon 只能构建 Ament 包吗?

colcon 是构建工具,支持多种构建器(ament_cmakeament_pythoncmakepython 等)。你甚至可以用 colcon 构建非 ROS 的纯 CMake 包。

Q4:学习 ROS 构建系统,我应该重点掌握什么?

  • 底层理解:CMake 的核心概念(目标、属性、查找包)。
  • ROS 层面 :熟悉 package.xml 的写法,以及对应的构建宏(catkin_*ament_*)。
  • 构建工具 :会用 catkin_make / colcon build 以及常用选项(--symlink-install--packages-select)。

八、总结

系统 本质 一句话总结
CMake 通用构建引擎 它什么都不懂,但什么都能造。
Catkin ROS 1 的 CMake 扩展 为 ROS 1 定制的"老爷车套件",功勋卓著但略显陈旧。
Ament ROS 2 的 CMake 扩展 为 ROS 2 全新设计的"现代套件",更干净、更灵活、更 Python 友好。

相关推荐
zhanglianzhao1 天前
Gazebo仿真机器人和相机时Gazebo ROS Control 插件偶发性加载失败bug分析
机器人·bug·ros·gazebo·ros_control
kobesdu2 天前
「ROS2实战-2」集成大语言模型:ollama_ros_chat 本地智能对话功能包部署和使用解析
人工智能·语言模型·自然语言处理·机器人·ros
kobesdu2 天前
〔ROS2 实战笔记-1〕Navigation2 导航框架解析
笔记·机器人·ros·路径规划
勤自省4 天前
ros生态系统
ros
kobesdu4 天前
ROS导航调参指南:机器人模型、TEB/DWA与Costmap全解析
人工智能·机器人·ros
勤自省4 天前
在Ubuntu20.04上安装ROS
linux·ros
CoderMeijun4 天前
CMake 入门笔记
c++·笔记·编译·cmake·构建工具
郝学胜-神的一滴4 天前
墨韵技术|CMake:现代项目构建的「行云流水」之道
c++·程序人生·软件工程·软件构建·cmake
H Journey5 天前
C++之 CMake、CMakeLists.txt、Makefile
开发语言·c++·makefile·cmake