Skip to content

构建系统(ament/colcon)

构建系统(build system)是帮助开发者编译 ROS 2 代码的工具。ROS 2 采用包(package)作为代码组织的基本单元,每个包都包含一个清单文件(package.xml),其中记录了包的元数据以及与其他包的依赖关系。元构建工具(meta-build tool)依赖此清单才能正常工作。

ROS 2 的构建系统由三个核心概念组成。

这类工具负责控制单个包的编译和测试。在 ROS 2 中,C++ 通常使用 CMake,Python 通常使用 setuptools,同时也支持其他构建工具。

这些是接入构建工具的辅助函数,旨在改善开发体验。ROS 2 包通常依赖 ament 系列包来提供这些功能。ament 由几个重要的仓库组成,它们都位于 GitHub 组织下。

该仓库位于 GitHub 上的 ament/ament_package,提供了一个 ament Python 包,为其他 ament 包提供各类实用工具,例如环境钩子(environment hooks)模板。

所有 ament 包都必须在其根目录下包含一个 package.xml 文件,无论底层使用什么构建系统。package.xml 清单文件包含了处理该包所需的信息,包括包的全局唯一名称和依赖项。此外,package.xml 还充当标记文件,用于标识包在文件系统中的位置。

package.xml 文件的解析由 catkin_pkg 提供(与 ROS 1 中相同),而通过在文件系统中搜索 package.xml 来定位包的功能,则由 colcon 等构建工具提供。

包的清单文件,用于标记包的根目录,并包含包的元信息,包括名称、版本、描述、维护者、许可证、依赖项等。清单内容采用机器可读的 XML 格式,具体规范在 REP 127 和 140 中定义,未来可能通过更多 REP 扩展。

因此,当某个包被称为 ament 包时,意味着它是一个由 package.xml 清单文件描述的独立软件单元(包含源代码、构建文件、测试、文档和其他资源)。

任何包含 package.xml 并遵循 ament 打包规范的包,无论其底层构建系统是什么。

由于 ament 包这个概念与构建系统无关,因此可以有不同类型的 ament 包,例如 ament CMake 包、ament Python 包等。

以下是你在该软件栈中可能遇到的常见包类型:

任何包含普通 CMake 项目和 package.xml 清单文件的包。

一种 CMake 包,同时遵循 ament 打包规范。

任何包含基于 setuptools 的 Python 项目和 package.xml 清单文件的包。

一种 Python 包,同时遵循 ament 打包规范。

该仓库位于 GitHub 上的 ament/ament_cmake,包含多个 “ament CMake” 包和纯 CMake 包,提供了创建 “ament CMake” 包所需的 CMake 基础设施。这里的 “ament CMake” 包指的是使用 CMake 构建的 ament 包。该仓库中的包提供了必要的 CMake 函数/宏和 CMake 模块,方便开发者创建更多的 “ament CMake”(或 ament_cmake)包。这类包通过 package.xml 文件中 <export> 标签内的 <build_type>ament_cmake</build_type> 来标识。

该仓库中的包高度模块化,但有一个名为 ament_cmake 的核心包作为聚合入口。只需依赖 ament_cmake,即可获取该仓库中所有包的聚合功能。以下是该仓库中的包及其简要说明:

  • ament_cmake

    • 聚合该仓库中的所有其他包,用户只需依赖此包即可
  • ament_cmake_auto

    • 提供便捷的 CMake 函数,自动处理编写包的 CMakeLists.txt 文件时许多繁琐的部分
  • ament_cmake_core

    • 为 ament 提供所有内置的核心概念,例如环境钩子、资源索引、符号链接安装等
  • ament_cmake_gmock

    • 为创建基于 gmock 的单元测试添加便捷函数
  • ament_cmake_gtest

    • 为创建基于 gtest 的自动化测试添加便捷函数
  • ament_cmake_nose

    • 为创建基于 nosetests 的 Python 自动化测试添加便捷函数
  • ament_cmake_python

    • 为包含 Python 代码的包提供 CMake 函数
    • 参见 ament_cmake_python 用户文档
  • ament_cmake_test

    • 使用 CTest 将不同类型的测试(如 gtest 和 nosetests)聚合到一个单一目标下

ament_cmake_core 包提供了大量 CMake 基础设施,使包与包之间可以通过约定接口干净地传递信息。这种解耦的构建接口提升了包的复用性,也促使不同包的构建系统遵循统一约定。例如,它提供了在包之间传递包含目录、库、定义和依赖项的标准方式,使用者可以按约定直接访问这些信息。

ament_cmake_core 还提供了符号链接安装功能,允许将源空间或构建空间中的文件以符号链接方式安装到安装空间,而非复制。这样只需安装一次,之后编辑非生成文件(如 Python 代码和配置文件)时无需重新运行安装步骤,更改即可立即生效。此功能基本上替代了 catkin 中的 “devel space”,既保留了大部分优点,又规避了其复杂性和缺点。

ament_cmake_core 提供的另一个功能是包资源索引,它允许包声明自己包含某种类型的资源。此功能使得一些常见问题(如”这个前缀(例如 /usr/local)下有哪些包?“)更容易回答,因为只需列出该前缀下某一固定位置的文件即可。更多详情请参阅资源索引的设计文档。

与 catkin 类似,ament_cmake_core 还提供了环境设置文件和针对包的环境钩子。环境设置文件(通常命名为 setup.bash 之类)用于定义使用某个包所需的环境变量。开发者通过”环境钩子”来实现这一点——环境钩子本质上是一段 shell 代码,可以设置或修改环境变量、定义 shell 函数、配置自动补全规则等。例如,ROS 1 就是通过此功能来设置 ROS_DISTRO 环境变量的,而 catkin 本身并不需要了解 ROS 发行版的信息。

该仓库位于 GitHub 上的 ament/ament_lint,提供了多个包,以方便、统一的方式进行代码检查和测试。目前支持的检查工具包括:使用 uncrustify 检查 C++ 代码风格、使用 cppcheck 进行 C++ 静态代码分析、检查源代码中的版权信息、使用 pep8 检查 Python 代码风格等。未来还会继续增加更多辅助包。

这类工具能够对一组包进行拓扑排序,并按照正确的依赖顺序构建或测试它们。它会调用构建工具来执行编译、测试和安装等实际工作。

在 ROS 2 中,用于此目的的工具是 colcon。